2013-02-21 66 views
4

編譯器優化有時可能會跳過對某些沒有結果的語句的評估。但是,這是否也適用於逗號運算符?編譯器能否跳過對逗號運算符左操作數的評估?

以下代碼在ideone上運行時沒有任何錯誤,但我預計它會崩潰。如果我改變了語句int x = 1/0;

+5

_Undefined_行爲與保證崩潰不同。 – jogojapan 2013-02-21 06:29:00

+0

不夠公平,但如果左操作數不是UB呢?編譯器能跳過它嗎? – 2013-02-21 06:46:08

+0

我相信這正如Alok在答案中所解釋的那樣,即它取決於是否有任何可觀察的事情發生。這是真的[不僅對於逗號運算符](http://stackoverflow.com/questions/3863656/how-to-cause-an-intentional-division-by-zero)。 (順便說一句,儘管我的評論,我認爲這是一個很好的問題,我+ 1的問題和答案。) – jogojapan 2013-02-21 06:48:01

回答

8

編譯器優化使用As-if rule

#include <iostream> 

int main() { 
    int x = (1/0, 2); 
    std::cout << x << std::endl; 
} 

該程序不會崩潰。

的是,如果規則

允許任何和所有的代碼轉換,不改變程序

所以是的,編譯器能夠優化這個的觀察到的行爲。檢查以下內容modified sample

#include <iostream> 

int main() 
{ 
    int y = 1; 
    int x = (y=1/0, 2); 
    std::cout << x << std::endl; 
    //std::cout << y << std::endl; 
} 

談到最後一行編譯並同時取消註釋它給你預期的不確定的行爲正確執行這個代碼。

由於@jogojapan正確指出,
重要的是要注意,編譯器優化不由標準保證,除以零是未定義的行爲。所以這段代碼確實有一個未定義的行爲。無論可觀察行爲是由於編譯器優化除以零還是由於未定義的行爲,我們都無法知道。從技術上講,這是未定義的行爲。

+2

我不認爲這很容易。什麼是「*可觀察行爲*」?如果它評估「1/0」,那麼你會「觀察」一個**不同的行爲。意思是,根據優化決定,程序的行爲是不同的。 – Nawaz 2013-02-21 06:16:24

+0

@Nawaz:在這種情況下,編譯器可以準確地檢測到逗號運算符的子表達式的評估結果從不使用,因此它可以簡單地優化它。如果使用此結果,編譯器不能也不會應用優化。 – 2013-02-21 06:18:25

+0

你的意思是,同一個程序對於不同的優化模式(以及不同的編譯器)會以不同的方式運行?那麼我認爲這不會是正確的。 – Nawaz 2013-02-21 06:20:13