byte b;
int i;
unchecked
{
b = 255 + 255; //overflows
i = 100 + int.MaxValue+100; // works
}
1)b表达式(b = 255 + 255;
)导致溢出错误的原因是由于受到两个冲突规则的影响,其中第一个规则 R1 表明:
类型的常量表达式(第7.19节) int可以转换为sbyte类型, byte,short,ushort,uint或ulong, 提供了价值 常量表达式在 目的地类型的范围。
第二个规则 R2 表示允许在未经检查的上下文溢出内。
在b表达式的情况下, R1 优先于 R2 ,因此常量表达式255+ 255
不在目标类型的范围内(哪个是字节), R1 会导致错误,即使 R2 允许溢出?
2)
a)我的理由是为什么表达式(i = 100 + int.MaxValue+100;
)不会导致错误:
1 - 当编译器开始计算i表达式时,它不会尝试在执行加法之前将值100
和int.MaxValue
提升为long
类型(因此在计算过程中两者值仍为int
}
2 - 添加会导致溢出,但由于这是在未经检查的上下文中发生的,因此不会引发错误
3 - 由于这两个值未升级为long
,因此结果值也为int
类型,因此结果值在目标类型范围内
b)但是,如果编译器确实提升了100
和int.MaxValue
;要在执行添加之前键入long
,那么i表达式会因违反规则 R1 而导致错误?!
感谢名单
答案 0 :(得分:1)
使用要添加到整数的字节,然后转换为字节,从而在转换(隐式)时导致溢出。
对于整数溢出只是重置从int.MinValue开始,所以结果将是int i = int.MinValue + 199;
编辑: 以下是可能的
byte b1 = (byte)255;
byte b2 = (byte)255;
byte b = (byte)(b1 + b2);
这是因为两个数字都存储为字节,并且总和在运行时转换,这不会产生常量表达式(因为b1和b2不被编译器称为常量)。
答案 1 :(得分:1)
是。默认情况下常量都是int
,因此第二个语句将快速溢出并保持在int内。如果你将其中一个常量变长,你可以看到它失败了:
byte b;
int i;
unchecked
{
b = 255 + 255; //overflows
i = 100L + int.MaxValue+100; // fails as well
}
答案 2 :(得分:0)
我认为关键是以下代码仍然“在目标类型范围内”
i = 100 + int.MaxValue + 100
溢出后,我将评估为-2147483449,这是一个有效的整数。
当添加255到255时,结果是510(整数),它远远超出字节类型的有效范围。这里没有溢出。
希望有所帮助