2014-02-22 200 views
1

我是通过“测试你的技巧在C”书 ,我发现这个问题与下面的代码太多初始化错误

char str[5]="abhisheksoni"; 

,这问题是:“这会不会产生任何类型的错误”练Ç问题 并且给出的答案是“如果超出数组范围,编译器从不检测错误”。 但是,当我编写这个程序错误“太多初始化”生成?

+0

编译器可以自由选择它如何处理展现未定义行为的程序。 –

+0

问:是编译器“错误”还是“警告”?还有:这本书是正确的,当代码是* EXECUTED *时,你不一定会得到* RUNTIME *错误。 – FoggyDay

+0

编译器检测此错误是微不足道的。但是“没有编译器从来没有检测到...”有两个负面因素,所以它确实意味着所有编译器有时会检测到:-) – juanchopanza

回答

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

没有编译器从未检测到错误,如果一个数组的边界被突破。

这是一个双重否定。在英语中,这与“每个编译器至少有时会检测到超出数组的范围”相同。提供太多的初始化程序可能会或可能不会被认为是这样。

无论如何,它是由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和footnote)。

奇怪的是,Clang和GCC在编译C和C++时将它标记为警告。这可能反映了在实践中的使用情况。

由于声明看起来就像一个错误,所以期望至少有一些编译器的警告消息是合理的,在任何情况下都是不合理的。当你知道这是错误的时候,为什么要问编译器?

+0

-1,因为C不允许这比C++更高。 – hvd

+0

@ hvd感谢您的纠正;我懒洋洋地接受了雷米贝尔的话。 – Potatoswatter

+0

Downvote删除,你的答案现在看起来不错。现在我只是感到困惑的问题(OP是否有错误或警告,如果出现错误,OP是否试图编译为C或C++):) – hvd

4

这本书是不正确的。该声明无效(即以C语言术语不规范或以C语言术语包含约束冲突),这是我们非正式地称为编译错误。这意味着任何符合要求的编译器都需要为此声明发布诊断消息。

值得一提的是C和C++语言在字符串初始值设定项方面略有不同,这些字符串初始值设定项过长了一个字符。C允许终止零落在数组的末尾,而C++不会。

char str[4] = "abcd"; // OK in C - produces a non-zero-terminated array 
         // Error in C++ 

但是,您的原始示例中,初始化字符过多长于一个字符,在两种语言中都不合格。

-1

没有一种机制保障是编译器会忽略或报告未定义行为

char ch[5]="abhisheksoni"; 

装置5个字节被保留,但您输入更多的,所以这是不确定的行为,并且会覆盖重要数据 所以不存在保证该编译器将显示错误,因为在我的系统中它正在工作

+0

它不是未定义的行为;这是一个需要诊断的错误。如果编译器在抱怨程序错误后选择生成可执行文件,那么可执行文件的行为是未定义的,但它超出了标准的范围。 – Potatoswatter