繁体   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