2014-02-22 219 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