为什么int i = 10;i / 0; 编译,但5/0给出CS0020-除以常数零?

Nic*_*ick 17 c#

考虑以下代码段:

int i = 5 / 0;
Run Code Online (Sandbox Code Playgroud)

这给出了编译器错误CS0020:除以常数0,这很好。但是,下一个代码段:

int i = 10;
i = i / 0;
Run Code Online (Sandbox Code Playgroud)

编译就好了。

有人知道为什么吗?我看不出为什么编译器允许将整数变量除以零整数常量。

Phi*_*p C 14

在一般情况下,编译器没有理由在运行时禁止除以零(或任何其他数字)。

但是,您的第一个示例是一个编译时间常数,即它是由编译器计算的,并由评估结果代替。这就是编译器所抱怨的,因为它不知道要用什么整数值代替5/0。

  • 这对于`anyInt / 0'不成立:编译器_could_知道它总是非法的。 (6认同)
  • @HenkHolterman:考虑到C#的隐式转换和运算符重载的高度灵活的规则,我怀疑有人写下带有整数类型`x`的文字`x / 0`表达式的特殊情况并不能保证发出一个警告/错误(仅此)。它总是将非常数表达式留给运行时。 (3认同)
  • @Stilgar我认为这是“您将在哪里划界线?”之一。案件。检查整数类型是否被常数整数零除很简单,但是您是否在局部分配的变量中检查零?有参数吗?鉴于开发人员不太可能直接在其代码中放入“ x / 0”(并且他们会在运行程序时找到它),这是不值得的。在编译时,检查是强制性的,因为它不能按原样编译。 (2认同)

meJ*_*rew 7

这只是编译时间检查和运行时检查之间的区别。而

i = i / 0;
Run Code Online (Sandbox Code Playgroud)

抛出

System.DivideByZeroException:'试图除以零。

i = 5 / 0;
Run Code Online (Sandbox Code Playgroud)

给出编译错误

错误CS0020除以常数零。

的值5 / 0是在编译时评估的,这就是导致接收错误和获取异常之间的区别。

编辑:

给定此处答案的注释,我将花一些时间来编写一个关于为什么编译器以这种方式工作的假设。编译器从未打算防止变量除以零。如果您愿意这样做,则可以这样做,并且可以用一些偷偷摸摸的方法来使程序除以零。编译器应该做的只是在可能的时候进行一些优化,通过计算它来进行微积分并将其替换为结果值。当它看到被零除时,由于无法计算,将给您一个错误。