2014-10-17 99 views
1

下面的C++代碼片斷計算斐波那契數字。對於32位整數,當n=47b變爲負數時,我們會溢出。簽名整數溢出到底片:這是一個編譯器錯誤,還是我誤解了優化?

int a=0, b=1, n=2; 
do { 
    a += b; int c = a; a = b; b = c; 
    ++n; 
} while (b>0 and n<50); 
std::cout << "Ended at n=" << n << " b=" << b << std::endl; 

在g ++ 4.9.1上編譯一切都很好;除非我使用-O2-O3,在這種情況下,循環運行至n=50。編譯器是否可能會假設,由於ab開始出現積極的情況,只有應用了補充,他們必須保持積極?看看裝配輸出確認條件b>0甚至沒有被檢查。

對於g ++ 4.7.0也是如此。所以我懷疑這是故意的行爲......?

+2

它是預期的,因爲它是根據標準的UB,如果你想定義它,使用'-fwrapv'。試圖查找重複,但無法找到規範的答案... – o11c 2014-10-17 20:25:24

+0

偉大的,非常感謝。有一些討論,例如http://thiemonagel.de/2010/01/signed-integer-overflow/ – 2014-10-17 20:31:05

+1

最高有效潛力dup:http://stackoverflow.com/questions/18195715/why-is-unsigned-integer-overflow-defined-behavior - 丁簽署整數溢出,是 – o11c 2014-10-17 20:51:58

回答

1

首先:此代碼根據[expr]/4調用未定義的行爲。因此,編譯器可以推斷,由於在沒有UB的情況下沒有負值可以分配給b(這種情況下編譯器不再考慮),所以b不能得到負值,因此不需要檢查該條件。

正如評論指出的那樣,標誌-fwrapvinstructs the compiler to

[...]假設加法,減法的簽署算術溢出和 乘法環繞使用二進制補碼錶示。這 標誌啓用一些優化並禁用其他。

由於GCC應該生成與優化級別低於O2相同的程序。

相關問題