int int1;
byte byte1;
unchecked
{
int1 = 2147483647 + 10; //ok
byte1 = 200+100; //error
}
1) int1
和 byte1
溢出之间的唯一区别是后者发生在收缩转换尝试期间,但最终结果(溢出)是相同的,所以为什么不编译器也会忽略 byte1
溢出(我知道编译器仅当值在该值的范围内时才允许将 int
类型的常量表达式转换为较小的类型目标类型,但我希望编译器忽略此类溢出(如果它们发生在未经检查的上下文中)?
2)检查和未检查的运算符/语句不是仅在运行时“事件”吗(即它们不只在运行时建立溢出检查上下文)吗?如果是这样,那么在上面的代码中,当 int1
溢出时,编译器也应该报告错误,因为在编译时会检查常量表达式,并且此时未经检查的语句尚未“事件”,因此它不会'尚未建立未经检查的溢出上下文吗?1
谢谢
最佳答案
1) 字节的常量表达式为 int
类型,具有 C# 4 规范第 6.1.9 节中指定的隐式转换:
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.
显然,常量表达式不在此处的目标类型范围内。
对于整数值,我相信它不会执行到 long
的提升,然后尝试执行到 int
的缩小转换 - 它正在使用 int 执行算术
溢出,根据第 7.19 节:
The compile-time evaluation of constant expressions uses the same rules as run-time evaluation of non-constant expressions, except that where run-time evaluation would have thrown an exception, compile-time evaluation causes a compile-time error to occur.
换句话说,常量表达式使用 +(int, int)
因为两个操作数都是整数...这在未经检查的上下文中不会提示,因为在执行时不会发生溢出时间也可以。
2) 不,选中和未选中在编译时也会有所不同。来自第 7.19 节:
Unless a constant expression is explicitly placed in an unchecked context, overflows that occur in integral-type arithmetic operations and conversions during the compile-time evaluation of the expression always cause compile-time errors (§7.19).
(出于兴趣,我想指出 Microsoft C# 编译器无论如何都不太符合中间引用段落的规则...有一些小数在编译时执行算术的结果与在执行时执行的相同操作不同的操作,IIRC。只是一些琐事。看看编译器即服务版本(即编译器即服务)是否会很有趣。托管代码)此处的行为方式相同。)
关于c# - Checked 和 Unchecked 不是只在运行时建立溢出上下文吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3621390/