2017-07-04 21 views
-2

我想了解我的C編程知識發生了什麼。讓我們先從一個經典問題(解引用未初始化的指針):爲什麼Clang支持取消引用未初始化的指針

int main(void) { 
    char *p; 
    *p = 'a'; 
    printf("%c\n", *p); 
    return 0; 
} 

這顯然是錯誤的!我知道。然而,當我在我的MacOS 10.12上運行LLVM Clang 8.1.0作爲編譯器時,它不僅未能檢測到未初始化的指針,而且還在屏幕上顯示了字符'a',就像沒有錯誤一樣。至少我期望像「分段錯誤」這樣的東西。

請您持思想和包涵了一會兒,看看下面的代碼:

int main(void) { 
    int i; 
    char **strPtr; 
    char *string = "Hello, world!"; 

    *strPtr = string; 

    printf("%s", *strPtr); 
    return 0; 
} 

這一次,我跑的代碼GCC-4.8.5已經成功地檢測到分段故障在第一碼。令我沮喪的是,字符串「你好,世界!」我在運行代碼後出現在屏幕上,就好像它沒有錯。

我想知道,既然strPtr也是一個指針(儘管是一個指向指針的指針),通過取消引用和賦值給strPtr,我不應該提交與第一個代碼中相同的錯誤嗎?

+2

告訴你的叮噹聲,你想讓它警告你這些東西('-Wall'),並且它應該考慮這樣的警告錯誤(' - 錯誤')。換句話說,使用例如'clang -Wall -Werror source.c -o binary'。 –

+0

你的指針不是未初始化的。任何神編譯器,包括鏗鏘都會警告一個無意義的轉換。如果你忽略它們(或者不啓用推薦的警告),那麼編譯器的錯誤不是 – Olaf

+0

「但是也顯示了結果」 - 哪個結果?該代碼沒有任何意義,但調用未定義的行爲。 – Olaf

回答

3

它不支持支持它;只是編譯器假定你知道你在做什麼。

這只是取消引用未初始化指針的行爲是未定義

它看起來工作是一種未定義行爲的體現。

記住古老的格言:C讓你有能力在腳下自我射擊。