2014-11-16 48 views
7

我明白,整數下溢和溢出未定義。爲什麼C++下溢/溢出行爲被認爲是未定義的?

但是,考慮到C++最終編譯爲程序集,是不是實際定義的行爲?

按位表示保持不變,整數格式保持不變0111..11總是會翻轉到1000..00,對於下溢也是如此,那麼爲什麼它不被視爲定義的行爲?

關於大會彙編,我是從我們被教導在學校簡陋的組裝,但是所代碼塊給

int x = INT_MAX; 
int y = x+1; 

編譯成

00401326 movl $0x7fffffff,0x8(%esp) 
0040132E mov 0x8(%esp),%eax 
00401332 inc %eax 
00401333 mov %eax,0xc(%esp) 

現在,無論x的值,不會總是有公司或增加指令?那麼,未定義的行爲在哪裏出現?

+0

這個問題很有趣,但我認爲你應該添加這兩種情況下的C++編碼示例,以及編譯器爲這些情況中的每一種生成的解構程序。 –

+0

我必須同意@barakmanos – MZaragoza

+0

它在C++中是未定義的,因爲世界上的各種CPU不同意定義。例如,某些CPU使用「飽和」數學,其中溢出導致最大值。 –

回答

5

C++標準中未定義有符號整數的溢出,這正是因爲不同的編譯器,彙編器和平臺可能會以不同的方式解釋這些。

當你知道一個將要運行的平臺時,你可以推理一個程序的行爲,但如果沒有這些知識,就無法預測它將如何運行。

按位表示保持不變,整數格式保持不變

這並不一定是真實的。

+0

謝謝,你能分享一種情況,在這種情況下,按位表示不會導致intmax + 1 = intmin,並且intmin-1 = intmax? – user87166

+2

@ user87166當編譯器優化它,因爲它總是UB。 – rightfold

+4

@ user87166 http://en.wikipedia.org/wiki/Signed_number_representations#Comparison_table – KoKuToru

6

但是,考慮到C++最終編譯爲程序集,是不是實際定義的行爲?

不,因爲編譯器決定它發出什麼樣的程序集。如果編譯器希望,它可以生成程序集,如果遇到未定義的行爲,它將擦除硬盤。

(實際上,它甚至有可能不會是真實的,「C++最終編譯成彙編」存在着C++ interpreters, for example - 。標準沒有規定如何/成什麼格式的C++應該編譯

其中一個原因標準的創建者決定讓它不確定是 - 幾乎總是 - - 優化的機會如果簽名溢出是UB,那麼編譯器可以假設x + 1 > x總是爲真,並生成更簡單/更短/更快的代碼,依賴於這個先決條件

0

IIRC,這是未定義的原因是因爲C++沒有要求如何存儲數字ta rget機器。

讓我們假設每個字節8位/ char。這將使我們:

  • std::numeric_limits<char>::max()
    • 2的補數:127(0b01111111)
    • 1的補數:127(0b01111111)
    • 簽名幅度:127(0b01111111)
  • std::numeric_limits<char>::min()
    • 2的補碼:-128(0b10000000)
    • 1的補碼:-127(0b10000000)
    • 符號的振幅:-127(0b11111111)

你已經可以看到的最低值,我們具有不同的位模式和最小值,而最大值是相同的。

那麼,如果你加1到最大值會發生什麼?假設我們投射到無符號數,加1,然後回到簽名。其結果將是:

  • 2的補碼:-128(0b10000000)
  • 1的補碼:-127(0b10000000)
  • 符號的振幅:-0(0b10000000)

相當混亂。但是如果我們想要使溢出定義清晰,我們可以做什麼?假設我們有一個signed char c = 127;並且想要加1.我們可以定義結果應該總是-127,因爲這就是所有三個被引用的系統可以表示的值(忽略它們不是表示有符號整數的唯一系統)。但這意味着編譯器必須專門捕獲該溢出,並在2的補碼(大多數系統)上正確處理它,並簽署幅度系統,這意味着額外的指令,因此在這些機器上的性能低於理想值。

你不可能遇到一臺在現實生活中沒有使用二進制補碼的機器,那麼C++的人不能簡單地強制它?我還沒有找到任何當前 CPU或DSP使用除補碼以外的任何東西,但返回時,當創建C++ 機器使用1的補碼(例如CDC Cyber),我不會驚訝聽到有些DSP今天還在做(畢竟有DSP有char sizes other than 8 bit)。這就是爲什麼它保持未定義的行爲。