5

看下面的代码,我只是想了解一下背后的原因......

const int a = 2147483647;
const int b = 2147483647;

int c = a + b; // it doesn't allow to compile!!! 

int a = 2147483647;
int b = 2147483647;

int c = a + b; // it allows to compile!!!
4

3 回答 3

4

const表达式在编译时解析,非const表达式在运行时解析。默认情况下,每个都有不同类型的溢出检查上下文。根据 C# 规范:

对于未被任何已检查或未检查的运算符或语句包围的非常量表达式(在运行时计算的表达式),默认溢出检查上下文是未检查的 ,除非外部因素(例如编译器切换和执行环境配置)需要检查评估。

这就是为什么在使用局部变量进行算术运算时没有看到运行时错误的原因。至于const计算:

对于常量表达式(可以在编译时完全求值的表达式),默认的溢出检查上下文总是被检查。除非将常量表达式显式放置在未经检查的上下文中,否则在表达式的编译时求值期间发生的溢出总是会导致编译时错误。

这就是您在const计算中看到编译时错误的原因。

有关 MSDN 上选中和未选中的更多信息

于 2012-12-07T01:49:08.183 回答
2

对于常量值,编译器本质上是在编译时用常量值替换变量。因此,在编译时计算加法语句时,它能够知道值并查看溢出情况。

对于整数类型变量,我认为编译器实际上并没有在编译时考虑分配的值,而是在运行时评估表达式。

但是 C# 证明默认情况下检查是禁用的。您可以在选项中打开它。请参阅 Justin Etheredge 关于原因和方法的优秀博客文章:

http://www.codethinked.com/c-trivia-what-no-overflow

于 2012-12-07T01:37:26.843 回答
0

我假设它是因为编译器知道const无法修改,所以a+b会失败。但是对于其他变量,它们可以在运行时更改,因此编译器不会假设设置的值不会更改为有效值。

于 2012-12-07T01:35:09.107 回答