我是通過「測試你的技巧在C」書 ,我發現這個問題與下面的代碼太多初始化錯誤
char str[5]="abhisheksoni";
,這問題是:「這會不會產生任何類型的錯誤」練Ç問題 並且給出的答案是「如果超出數組範圍,編譯器從不檢測錯誤」。 但是,當我編寫這個程序錯誤「太多初始化」生成?
我是通過「測試你的技巧在C」書 ,我發現這個問題與下面的代碼太多初始化錯誤
char str[5]="abhisheksoni";
,這問題是:「這會不會產生任何類型的錯誤」練Ç問題 並且給出的答案是「如果超出數組範圍,編譯器從不檢測錯誤」。 但是,當我編寫這個程序錯誤「太多初始化」生成?
沒有必要爲每個編譯器提出任何錯誤或警告。一些編譯器可能會拋出(編譯在C99模式:-Wall -Wextra -pedantic -g3 -std=c99
):警告
[Warning] initializer-string for array of chars is too long [enabled by default]
最好使用
char str[]="abhisheksoni";
沒有編譯器從未檢測到錯誤,如果一個數組的邊界被突破。
這是一個雙重否定。在英語中,這與「每個編譯器至少有時會檢測到超出數組的範圍」相同。提供太多的初始化程序可能會或可能不會被認爲是這樣。
無論如何,它是由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++時將它標記爲警告。這可能反映了在實踐中的使用情況。
由於聲明看起來就像一個錯誤,所以期望至少有一些編譯器的警告消息是合理的,在任何情況下都是不合理的。當你知道這是錯誤的時候,爲什麼要問編譯器?
-1,因爲C不允許這比C++更高。 – hvd
@ hvd感謝您的糾正;我懶洋洋地接受了雷米貝爾的話。 – Potatoswatter
Downvote刪除,你的答案現在看起來不錯。現在我只是感到困惑的問題(OP是否有錯誤或警告,如果出現錯誤,OP是否試圖編譯爲C或C++):) – hvd
這本書是不正確的。該聲明無效(即以C語言術語不規範或以C語言術語包含約束衝突),這是我們非正式地稱爲編譯錯誤。這意味着任何符合要求的編譯器都需要爲此聲明發布診斷消息。
值得一提的是C和C++語言在字符串初始值設定項方面略有不同,這些字符串初始值設定項過長了一個字符。C允許終止零落在數組的末尾,而C++不會。
char str[4] = "abcd"; // OK in C - produces a non-zero-terminated array
// Error in C++
但是,您的原始示例中,初始化字符過多長於一個字符,在兩種語言中都不合格。
沒有一種機制保障是編譯器會忽略或報告未定義行爲
char ch[5]="abhisheksoni";
裝置5個字節被保留,但您輸入更多的,所以這是不確定的行爲,並且會覆蓋重要數據 所以不存在保證該編譯器將顯示錯誤,因爲在我的系統中它正在工作
它不是未定義的行爲;這是一個需要診斷的錯誤。如果編譯器在抱怨程序錯誤後選擇生成可執行文件,那麼可執行文件的行爲是未定義的,但它超出了標準的範圍。 – Potatoswatter
編譯器可以自由選擇它如何處理展現未定義行爲的程序。 –
問:是編譯器「錯誤」還是「警告」?還有:這本書是正確的,當代碼是* EXECUTED *時,你不一定會得到* RUNTIME *錯誤。 – FoggyDay
編譯器檢測此錯誤是微不足道的。但是「沒有編譯器從來沒有檢測到...」有兩個負面因素,所以它確實意味着所有編譯器有時會檢測到:-) – juanchopanza