,如果我做這樣的事情會發生什麼:當我從C++中的有符號整數中減去一個無符號整數時會發生什麼?
unsigned int u;
int s;
...
s -= u;
什麼的這種預期的行爲:
1)假設無符號整數,是不是太大,不適合在有符號整數?
2)假設無符號整數會溢出有符號整數?
謝謝。
,如果我做這樣的事情會發生什麼:當我從C++中的有符號整數中減去一個無符號整數時會發生什麼?
unsigned int u;
int s;
...
s -= u;
什麼的這種預期的行爲:
1)假設無符號整數,是不是太大,不適合在有符號整數?
2)假設無符號整數會溢出有符號整數?
謝謝。
一般來說,請參閱標準中的5/9。
在您的例子中,簽署值轉換爲無符號(通過取它MOD UINT_MAX + 1),則減法完成模UINT_MAX + 1,得到一個無符號的結果。
將此結果作爲有符號值存儲到s
涉及標準積分轉換 - 這是4.7/3。如果該值在signed int
的範圍內,則保留該值,否則該值是實現定義的。我曾經看過的所有實現都使用模算術將它推到INT_MIN
到INT_MAX
的範圍內,但是Krit說你可能會隱含地做出這樣的警告。
您可能永遠不會處理的「特技」實現對於無符號 - >有符號轉換可能有不同的規則。例如,如果實現具有符號整數的符號幅度表示,則不可能總是通過取模來進行轉換,因爲無法將+/- (UNIT_MAX+1)/2
表示爲整數。
相關的還有5.17/7「的形式E1 op= E2
的表達式的行爲等同於除了E1
E1 = E1 op E2
只計算一次」。這意味着爲了說減法是在unsigned int
類型中完成的,我們需要知道的是s - u
在unsigned int
中完成:對於-=
沒有特別的規則,算術應該在LHS的類型中完成。
只需提醒一下,「實現定義的結果」可能是「實現定義的信號」,即 。 (C標準在這方面更清晰。) 實際上,您會在兩個 補充機器上得到正確的結果,其他地方的結果不正確。 – 2011-03-16 17:20:16
@James:我認爲那是C++和C之間的故意區別。 C++的措辭非常明確,「價值是實現定義的」。它沒有說「行爲是實現定義的」,它會允許一個信號。 – 2011-03-16 17:23:20
可能的重複[在C中籤名爲無符號轉換 - 它總是安全嗎?](http://stackoverflow.com/questions/50605/signed-to-unsigned-conversion-in-c-is-it-always -safe) – 2011-03-16 17:09:38
不完整重複。這個問題最後被賦值爲一個'unsigned'變量,所以算法是相同的,但最後的賦值是不同的。 – 2011-03-16 17:17:41
也值得看看:[*是無符號整數減法定義的行爲?](http://stackoverflow.com/q/7221409/1168156):) – LihO 2013-02-24 16:38:58