我尝试了以下代码:
int x, y;
x = y = int.MaxValue;
int result = x + y;
这段代码运行良好,结果将包含-2(我知道原因)。
但是当进行以下操作:
const int x = int.MaxValue;
const int y = int.MaxValue;
int result = x + y;
这段代码由于溢出问题无法编译通过。为什么?
我尝试了以下代码:
int x, y;
x = y = int.MaxValue;
int result = x + y;
这段代码运行良好,结果将包含-2(我知道原因)。
但是当进行以下操作:
const int x = int.MaxValue;
const int y = int.MaxValue;
int result = x + y;
这段代码由于溢出问题无法编译通过。为什么?
由于x
和y
都是编译时常量,所以x + y
也是。编译器“知道”结果会溢出,因此会报错。
您可以通过使用unchecked
表达式来修复此问题:
int result = unchecked(x + y);
来自 C# 5 规范第 7.6.12 节 - 在列出 +
, -
, /
和 *
后:
当上述运算之一产生的结果过大而无法表示为目标类型时,执行操作的上下文控制生成的行为:
- 在
checked
上下文中,如果操作是常量表达式(§7.19),则会导致编译时错误。- 在
unchecked
上下文中,结果将通过丢弃任何不适合目标类型的高位比特来截断。对于非常量表达式(在运行时评估的表达式)不被任何
checked
或unchecked
运算符或语句包围的情况下,默认的溢出检查上下文是unchecked
,除非外部因素(例如编译器开关和执行环境配置)要求进行 checked 评估。对于常量表达式(可以在编译时完全计算的表达式),默认的溢出检查上下文始终为
checked
。除非将常量表达式明确放置在unchecked
上下文中,否则在表达式的编译时评估过程中发生的溢出总会导致编译时错误。
int
(有符号),从十六进制表示中进行转换。它看起来像是 int hr = unchecked((int)0x80070005);
。 - Jeppe Stig Nielsen