为什么CLR不编译溢出const,但对于变量它呢?

时间:2012-12-07 01:28:21

标签: c# .net clr

请参阅下面的代码,我只是想了解背后的原因......

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!!!

3 个答案:

答案 0 :(得分:4)

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

  

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

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

  

对于常量表达式(可以在。处完全计算的表达式)   编译时),始终是默认的溢出检查上下文   检查即可。除非将一个常量表达式明确放在一个   未经检查的上下文,在编译期间发生的溢出   表达式的计算总是会导致编译时错误。

这就是为什么您的const计算出现编译错误的原因。

More information about checked and unchecked on MSDN

答案 1 :(得分:2)

对于常量值,编译器实际上在编译时用常量值替换变量。因此,当在编译时评估addition语句时,它能够知道这些值并查看溢出条件。

对于整数类型变量,我认为编译器实际上并不在编译时考虑赋值,而是在运行时计算表达式。

但是C#证明默认情况下禁用了检查。您可以在选项中打开它。请参阅Justin Etheredge关于他们的优秀博客文章以及如何:

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

答案 2 :(得分:0)

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