如果使用變數x而不是0輸出將是Hello. 如果您使用0編譯器將顯示關于除以零的警告。代碼如下:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int x = 0;
if (5 < 4 & (7 / x) == 0)
puts("dividing by zero");
else
{
puts("Hello");
}
return 0;
}
uj5u.com熱心網友回復:
5 < 4is always 0,并且7 / x是一個沒有可見副作用的運算式(由標準定義為檔案 IO 或對volatile變數的訪問,具體實作可能會提供更廣泛的保證);由于計算最終結果不需要該子運算式,因此編譯器有權對其進行優化。
在其他情況下(當該操作實際上是在運行時執行時,或者當它在編譯時完全知道時,如您的問題),等效運算式可能會在運行時使程式崩潰或給出編譯時警告/錯誤,這是允許的好吧:除以零是未定義的行為,因此允許編譯器做任何事情(包括假設優化時不會發生)。
uj5u.com熱心網友回復:
運算式(5 < 4 & (7 / x) == 0)被決議為
((5 < 4) & ((7 / x) == 0))
問題是你有未定義的行為,無論使用x還是0任何事情都可能發生,并且 C 標準沒有定義編譯器應該做什么。查看godbolt.org上的編譯器輸出,程式的行為因不同的編譯和不同的編譯器選項而異。
編譯器計算(5 & 4)為一個值為 的常量運算式0。除了定義為undefined的未定義行為之外,右運算元((7 / x) == 0)沒有任何可觀察到的副作用。如果啟用了優化,編譯器似乎會忽略潛在的未定義行為,并在編譯時確定整個運算式的值為. 因此不進行測驗,只需要呼叫。7 / x0puts("Hello");
如果x用它的 value替換0,因為編譯器將整個運算式評估為常量運算式,它不能忽略((7 / 0) == 0)具有未定義行為的事實,因此它會生成診斷,但似乎仍然忽略未定義行為,整個運算式仍然有一個值的0所以同樣puts("Hello")產生。
未定義的行為是未定義的,因此假設它只產生一些值是合法的并且0 & some_value是0,這使得測驗總是采用else分支。
如果禁用優化,代碼生成會發生變化,并且除法0會發生任何副作用(在 x86 處理器上引發信號)或發生其他一些奇怪的副作用(例如運算式始終為真clang -O0)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/491240.html
