簡體   English   中英

為什么x = x + 100的處理方式不同於x + = 100,它們編譯為相同的IL?

[英]Why is x = x + 100 treated differently than x += 100 that compiles to the same IL?

我們知道這兩個加法語句是等價的,並編譯為相同的IL代碼:

int x = 100;

x += 100;
x = x + 100;

但是,當需要明確的演員表時我發現​​了一些奇怪的東西:

byte b = 100;

b += 200; // Compiles (1)
b = b + 200; // Cannot implicitly convert int to byte (2)
b = (byte) (b + 200); // Compiles (3)

很明顯,為什么第二個語句需要顯式轉換,因為加法的結果是整數。 但對我來說奇怪的是第一個聲明。 它編譯為與第三個語句完全相同的IL,因此看起來編譯器為我們添加了一個應該是顯式的強制轉換。 但它不能在第二個聲明中這樣做。

這對我來說似乎是矛盾的,因為我希望第一個語句等同於第二個語句並且永遠不會編譯,所以它為什么要編譯?

注意:當從longint需要顯式強制轉換時,這不會編譯:

int x = 100;
long y = 200;

x += y;

你真的需要去了解這類信息的規格 (並且很難理解這些措辭)。 但是,直接從馬口

12.18.3復合賦值

x op= y形式的x op= y通過應用二元運算符重載決策(第12.4.5節)來處理,就好像操作是在x op y.中編寫的一樣x op y. 然后,

  • 如果所選運算符的返回類型可隱式轉換為x的類型,則操作將計算為x = x op y ,但x僅計算一次。

  • 否則,如果所選運算符是預定義運算符,如果所選運算符的返回類型可顯式轉換為x類型,並且如果y可隱式轉換為x類型或運算符是移位運算符,則操作被評估為x = (T)(x op y) ,其中Tx的類型,除了x僅被計算一次。

  • 否則,復合賦值無效,並發生綁定時錯誤。

...

等等等等等等

...

上面的第二條規則允許在某些上下文中將 x op= y計算為x = (T)(x op y) 存在這樣的規則: 當左操作數是sbytebyteshortushortchar類型時 ,預定義運算符可以用作復合運算符 即使兩個參數都屬於這些類型之一,預定義運算符也會生成int類型的結果,如第12.4.7.3節中所述。 因此,如果沒有強制轉換,則無法將結果分配給左操作數

對於預定義的運算符規則的直觀的效果僅僅是x op= y是如果同時滿足允許的x op yx = y是允許的

 byte b = 0; char ch = '\\0'; int i = 0; b += 1; // Ok b += 1000; // Error, b = 1000 not permitted b += i; // Error, b = i not permitted b += (byte)i; // Ok ch += 1; // Error, ch = 1 not permitted ch += (char)1; // Ok 

每個錯誤的直觀原因是相應的簡單分配也是一個錯誤。

簡而言之,計算機說沒有。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM