2011-04-11 73 views
2
byte b; 
int i; 

unchecked 
{ 
    b = 255 + 255; //overflows 
    i = 100 + int.MaxValue+100; // works 

} 

1)內溢出錯誤是爲什麼B表達的影響(b = 255 + 255;)導致溢出錯誤,由於受着兩個相互矛盾的規則,其中第一條規則R1狀態的原因:獲取選中聲明

A constant-expression (§7.19) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type.

而第二個規則R2指出在未檢查的上下文中允許溢出。

,在b表達的情況下,R1優先R2,因此由於常量表達式255+ 255不是目標類型(這是字節)的範圍內,R1導致錯誤,甚至儘管R2允許溢出?

2)

A)這是我的推理,爲什麼我的表達(i = 100 + int.MaxValue+100;)不會導致錯誤:

1 - 當編譯器開始計算我的表達,它不會嘗試推廣值100int.MaxValue執行添加之前鍵入long(在計算過程從而這兩個值int類型的靜止)

2 - 加入不導致溢出,但由於這種情況發生未檢查康特內XT,不會引發錯誤

3 - 由於兩個值沒有得到提升到long,所得到的值是int類型的也正因爲如此所得到的值是目標類型

B的範圍內)但是如果編譯器確實促進了100int.MaxValue;在執行添加之前鍵入long,那麼i表達式會因違反規則R1?造成錯誤!

感謝名單

+2

有趣的分析 - 什麼是問題? – Hogan 2011-04-11 19:24:24

+0

問題是我的推理是否正確:) – user702769 2011-04-11 19:41:45

+1

除了錯誤地將規則描述爲「衝突」之外,您的分析是正確的。你爲什麼認爲這些規則有衝突?規則1並不是「優先於」另一方。這兩條規則同樣適用。 「字節b = 510;」無論上下文是選中還是未選中都是非法的。 – 2011-04-11 19:49:27

回答

1

是的。常量默認全部爲int,所以第二個語句會很快地溢出並保持在int內。你可以看到它,如果你做的常量長的一個失敗:

byte b; 
int i; 

unchecked 
{ 
    b = 255 + 255; //overflows 
    i = 100L + int.MaxValue+100; // fails as well 
} 
+0

所以我正確地認爲由於規則R1優先於R2而導致b表達式導致錯誤? – user702769 2011-04-11 19:42:21

+0

是的。在'i'的情況下,不會發生轉換,因此規則** R1 **根本不適用。 – ChrisWue 2011-04-11 20:22:04

+0

謝謝大家的幫助 – user702769 2011-04-11 22:21:43

1

隨着要添加到整數,然後轉換爲一個字節,因此在轉換時(隱式地)使溢出的字節。 用整數溢出只是重置爲int.MinValue開始,所以其結果必然是int i = int.MinValue + 199;

編輯: 以下是可能的,雖然

byte b1 = (byte)255; 
byte b2 = (byte)255; 
byte b = (byte)(b1 + b2); 

這是因爲這兩個號碼存儲爲字節, sum在運行時被轉換,不會產生一個常量表達式(因爲編譯器不知道b1和b2是常量)。

+0

這不完全正確。 '字節b =(字節)(b1 + b2);'可以完成,因爲你明確地將'int'轉換爲'byte'。如果你刪除了顯式的轉換,那麼你會發現編譯器會抱怨,因爲增加兩個字節會產生一個'int'。你也可以做'byte b =(byte)(255 + 255)'。儘管編譯器沒有將'b1 + b2'優化爲'510',我有點驚訝。也許留給JIT的東西。 – ChrisWue 2011-04-11 20:34:07

0

我認爲最關鍵的是,下面的代碼仍然是

i = 100 + int.MaxValue + 100 

後「的目標類型的範圍內」溢出,我將評估-2147483449這是一個有效的整數。

當添加255到255時,結果是510(整數),它遠遠超出字節類型的有效範圍。這裏沒有發生溢出。

希望有幫助