2013-08-31 30 views
2

令人驚訝的是,我發現gcc編譯C時可以發現這個錯誤。我簡化了仍然觸發警告的代碼。我發佈了這個問題,以澄清它使用的技術的細節。下面是我的文件的代碼a.cgcc檢測「subindex out of bound」錯誤

int main(){ 
    int a[1]={0}; 
    return(a[1]); 
} 

我的gcc版本是gcc (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3。當使用gcc a.c -Wall時,沒有警告;使用gcc -O1 a.c -Wall的時候,有一個警告:

warning: ‘a[1]’ is used uninitialized in this function [-Wuninitialized] 

,並使用gcc -O2 a.c -Wall(或-O3)時,還有另外一個警告:

warning: array subscript is above array bounds [-Warray-bounds] 

最令人驚奇的是,當我給a[1]值,那麼上述編譯選項都不會給出任何警告。沒有任何警告,甚至當我改變索引數量龐大(當然編譯的文件冒犯的操作系統,將被踢出),

int main(){ 
    int a[1]={0}; 
    a[2147483648]=0; 
    return(a[2147483648]); 
} 

我認爲,上述現象是多了一個函數錯誤。我希望有人幫助我弄清楚會發生什麼,以及/或者爲什麼編譯器是這樣設計的。非常感謝!

回答

4

訪問陣列末尾的內存導致undefined behaviour

gcc已經足夠好了,可以用它來檢測並警告你這些錯誤。不過,它沒有這樣做的義務,當然也不可能趕上所有這樣的錯誤。

+0

好吧,明白了。謝謝。但是,由於'gcc'想這樣做,我想知道是否有任何理由,在某些情況下,它不能捕捉到所有這些錯誤。我知道一個編譯器不會運行你的代碼(這在科學計算中尤其如此),但是邊界在哪裏? –

+1

@xinguo很難確切地知道它在哪裏。有些編譯器更聰明,有些編譯器不太聰明,但有一點是肯定的:有些問題在編譯時根本無法檢測到。 – 2013-08-31 21:12:37

+1

我認爲,檢測* all *個案中的這種出界索引可以證明與[halting problem]相同(http://en.wikipedia.org/wiki/Halting_problem) –

4

編譯器不需要爲這類錯誤提供診斷,但gcc經常能夠提供幫助;請注意,這些警告通常部分地作爲用於優化目的的靜態分析過程的副產品而出現,這意味着,正如您注意到的那樣,此類警告通常取決於指定的優化級別。