2015-07-04 75 views
3

有人可以解釋一下爲什麼在C/C++中爲什麼某些4字節整數的右邊32位按位移可能返回不爲零?爲什麼它取決於編譯器的-O選項?爲什麼`int >> 32`不總是爲零?

例如該代碼給出了45 -O0和0與-O3選項GCC 4.8.3:

unsigned int x = 45; // 4 bytes 
x = x >> 32; 
printf("%u\n", x); 

爲什麼是這樣呢?

回答

22

因爲它是未定義的行爲:[expr.shift]

的行爲是不確定如果將右操作數是負的,或者大於或等於在推動左操作數的位長度。

至於具體不確定的行爲,我想這是如下:

  • 隨着-O0,它編譯成實際執行的機器代碼右移,並在某些機器(例如I相信x86是這樣的),移位功能僅在移位32位字時才查看移位量的低5位;移位32與移位0相同。
  • 對於-O3,編譯器自己計算常量,並將0放入程序中,而不是進行計算。

您可以檢查程序集輸出以查看我的預測是否正確。

+0

我期待第二種行爲,但是在我的代碼中,這取決於這種行爲並且使用-O3標誌編譯,我確實有32個移位的非零結果。也許是因爲編譯器不一致地執行-O3優化。所以,在一天結束的時候,你不能依賴這個。如你所說,它是不確定的。 –

+0

PS:但我認爲這是不對的,應該定義:來自左側的位應該是零。期。 - –

相關問題