我被要求说明以下代码段是否触发任何错误或警告:
char string[5] = "hello";
我已经在我的计算机上测试了它,它工作得很好(没有错误/警告,printf
给出了期望值("hello"),strlen
给出了期望值(5))。然而,我想说这产生了某种未定义的行为。我想这被认为是一个坏的做法,但它会导致一个错误,因为我们没有明确地允许一个字节的空字符?
允许。来源:K&R C, ANSI C版本。一个字符数组可以用包含这么多字符的字符串初始化。这将导致一个不以null结尾的字符串——请谨慎使用。这意味着printf("%s", string);
没有定义,但printf("%.5s", string);
是定义的。
看似有效是未定义行为的可能结果。事实上,在这样的示例中,文件.data
区域中的最后一个内容将是字符串,然后用零填充以匹配机器对齐。在堆栈上,当程序第一次启动时,main
中未初始化的内存往往具有相同的归零条件(并非总是如此,任何代码都不应该依赖于此)。从而导致一切似乎都在工作。但是当程序变大时,它会莫名其妙地停止工作,因为内存布局或初始化发生了变化。
在C中,编译器将允许这样做,相当于
char string[5] = { 'h', 'e', 'l', 'l', 'o' };
请注意,不会是添加的字符串空终止符。
参见数组初始化参考。
还请注意,这是C与c++不同的许多地方之一,在这些地方不允许这样做。