16

從C++標準的部分§3.9.1/ 6說,bool類型樂趣未初始化的變量和編譯器(GCC)

值可以是truefalse

現在考慮這個代碼,

void f(bool b) 
{ 
    switch(b) //since b is bool, it's value can be either true or false! 
    { 
     case true: cout << "possible value - true"; break; 
     case false: cout << "possible value - false"; break; 
     default: cout << "impossible value"; 
    } 
} 
int main() 
{ 
    bool b; //note : b is uninitialized 
    f(b); 
    return 0; 
} 

編譯F:\workplace>g++ test.cpp -pedantic

運行。輸出:

不可能值

意外的輸出?嗯,不是真的,作爲標準在§3.9.1/ 6註腳寫着:

使用的方式一個布爾值來描述 本國際標準爲 「未定義」通過檢查 未初始化的值自動對象, 可能會導致它到表現得好像它是 既不是真也不是假

所以無論我編譯和運行這個程序多少次,我都會得到相同的輸出:impossible value。但是,如果我改變了一點 - 消除圖像的功能f(),並在main()switch塊本身:

int main() 
{ 
    bool b; //note : b is uninitialized 
    switch(b) //since b is bool, it's value can be either true or false! 
    { 
     case true: cout << "possible value - true"; break; 
     case false: cout << "possible value - false"; break; 
     default: cout << "impossible value"; 
    } 
    return 0; 
} 

然後我編譯並運行這個程序,我不明白impossible value的輸出;不管我多次重複這個,我永遠都不會得到impossible value

我只是好奇,想知道爲什麼在未初始化的布爾行爲這突如其來的變化?

好了,從語言的角度很明顯:該行爲是undefined.I理解。我也明白編譯器可以自由地做任何事情。然而,從編譯器的角度來看,這對我來說似乎很有意思。什麼可以在編譯(即GCC)可能在每種情況下,爲什麼呢?

我使用:g++ (GCC) 4.5.0 - MinGW, on Windows 7 Basic, 64-bit OS

+1

我不能用g ++ - 4.4.5 amd64來複制你的結果。但是如果你想回答自己這類問題,爲什麼不檢查編譯器彙編輸出? – BatchyX 2011-02-02 19:48:08

回答

17

我只是好奇地想知道爲什麼這個未初始化布爾行爲的突然變化?

拆卸代碼,看看編譯器的做。

我的猜測:因爲值現在只能在本地使用,編譯器優化完全它拿走。由於行爲不確定,因此編譯器可以安全地假設任何值,例如false。這是一個非常明顯的優化,因爲就編譯器而言,b的值是恆定的,並且switch的整個邏輯是多餘的。那麼爲什麼把它放在可執行文件中? (這裏很重要的一點是,b只能在第二個代碼中本地使用,並且反過來也會觸發更多的優化,即使在未優化的代碼中。第一個代碼必須在編譯器可以執行任何操作之前進行內聯優化或代碼路徑必須被追蹤,這不是微不足道的)。