在未经检查的语句中出现溢出错误

时间:2011-04-11 19:22:09

标签: c#

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表达式时,它不会尝试在执行加法之前将值100int.MaxValue提升为long类型(因此在计算过程中两者值仍为int}

类型

2 - 添加会导致溢出,但由于这是在未经检查的上下文中发生的,因此不会引发错误

3 - 由于这两个值未升级为long,因此结果值也为int类型,因此结果值在目标类型范围内

b)但是,如果编译器确实提升了100int.MaxValue;要在执行添加之前键入long,那么i表达式会因违反规则 R1 而导致错误?!

感谢名单

3 个答案:

答案 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(整数),它远远超出字节类型的有效范围。这里没有溢出。

希望有所帮助