我通过“测试你的c技能”书来练习c个问题 我用以下代码找到了这个问题
char str[5]="abhisheksoni";
这个问题是“这会产生任何类型的错误” 给出的回答是“如果超出数组边界,则编译器永远不会检测到错误。” 但是当我编写这个程序时出现错误“Too many initialization”生成了??
答案 0 :(得分:4)
这本书不正确。声明无效(即C ++术语中的格式错误的,或者在C术语中包含约束违规),这就是我们非正式地称之为编译错误。这意味着需要任何符合要求的编译器为此声明发出诊断消息。
值得补充的是,C和C ++语言在字符串文字初始值设定项方面略有不同,这些字符串文字初始值设定项的长度超过一个字符。 C允许终止零点从数组的末尾开始,而C ++则没有。
char str[4] = "abcd"; // OK in C - produces a non-zero-terminated array
// Error in C++
但是你的原始示例,其中初始化文字的长度超过一个字符,在两种语言中都是不正确的。
答案 1 :(得分:3)
如果超出数组的边界,则编译器永远不会检测到错误。
这是一个双重否定。在英语中,这与“每个编译器至少有时检测到超出数组范围”相同。提供太多的初始化程序可能会或可能不会被视为这样。
无论如何,C11§6.7.9/ 2禁止使用:
初始化程序不应尝试为未初始化的实体中包含的对象提供值。
和C ++11§8.5.2/ 2 [dcl.init.string]:
没有比数组元素更多的初始化器。
但是,当程序包含非法内容时,C和C ++不需要打印任何消息。该消息可以仅被标记为警告,并且程序仍然编译并运行。 (C ++11§1.4/ 2;C11§5.1.1.3/ 1和脚注。)
奇怪的是,Clang和GCC在编译C时将其标记为警告,并为C ++编写错误。这或许反映了在实践中的使用情况。
由于声明看起来像错误,所以至少期望来自某个编译器的警告消息是合理的,并且在任何情况下无意地无意地执行它。当你知道它错了时,为什么要问编译器呢?
答案 2 :(得分:2)
没有必要为每个编译器引发任何错误或警告。某些编译器可能会发出警告(在C99模式下编译为:-Wall -Wextra -pedantic -g3 -std=c99
):
[Warning] initializer-string for array of chars is too long [enabled by default]
最好使用
char str[]="abhisheksoni";
答案 3 :(得分:-1)
没有保证编译器会忽略或报告未定义的行为
char ch[5]="abhisheksoni";
表示保留5个字节,但您输入的更多,因此这是未定义的行为,可能会覆盖重要数据 所以不保证编译器会在我的系统中显示错误