Pal*_*Dot 8 c arrays compilation
我在一本书中读到了这个问题及其答案.但我不明白这本书的理由.
下面的代码会编译吗?
int main()
{
char str[5] = "fast enough";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
答案是:
是的.如果超出数组的边界,编译器永远不会检测到错误.
我无法得到它.
有人可以解释一下吗?
在C++标准中,8.5.2/2字符数组表示:
没有比数组元素更多的初始化器.
在C99标准中,6.7.8/2初始化说:
初始化程序不应尝试为未初始化的实体中包含的对象提供值
C90 6.5.7初始化器说类似.
但请注意,对于C(C90和C99),如果有空间,'\ 0'终止字符将被放入数组中.如果终止符不适合,则不是错误(C99 6.7.8/14:"字符串文字的连续字符(如果有空间或数组大小未知,则包括终止空字符)初始化元素阵列").
另一方面,C++标准有一个例子,表明如果终止字符没有空间,应该诊断错误.
在任何一种情况下,这应该被诊断为所有编译器中的错误:
char str[5] = "fast enough";
Run Code Online (Sandbox Code Playgroud)
也许前ANSI编译器不是那么严格,但任何合理的现代编译器都应该诊断出来.
你的书必须很旧,因为即使没有-Wall
开启,gcc也会发出警告:
$ gcc c.c c.c: In function `main': c.c:6: warning: initializer-string for array of chars is too long
如果我们稍微更新程序:
#include <stdio.h>
int main(int argc, char **argv)
{
char str[5] = "1234567890";
printf("%s\n", str);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我们可以看到gcc似乎将字符串截断为你指定的长度; 我假设有恰好是一个'\0'
在那里str[6]
会是这样,因为否则我们应该在5后看到垃圾; 但也许gcc隐含地制作str
一个长度为6的数组并自动将其固定'\0'
在那里 - 我不确定.
$ gcc c.c && ./a.exe c.c: In function `main': c.c:6: warning: initializer-string for array of chars is too long 12345