未经检查的 C# 块中的 System.OverflowException

问题描述

如果我将 Int32.MinValue 和 -1 传递给 Divide() 方法,尽管该块发生在 System.OverflowException 块中,但我仍会得到一个 unchecked

    private static int Divide(int n,int d)
    {
        return unchecked (n / d);
    }

这让我感到惊讶 - 除非我错误地阅读了 documentation 的检查/未检查,否则我希望它只会给我一个溢出的输出(因为 Int32.MinValue / -1 = 2^31 = Int32.MaxValue + 1,我期望溢出到 Int32.MinValue 的值)。相反,它抛出了一个 OverflowException

这是显示问题的 DotNetFiddle

解决方法

From the C# draft specification on integer division

如果左操作数是最小可表示的 intlong 值,而右操作数是 -1,则发生溢出。在 checked 上下文中,这会导致抛出 System.ArithmeticException(或其子类)。在 unchecked 上下文中,它是实现定义的,即是抛出 System.ArithmeticException(或其子类)还是未报告溢出,结果值是左操作数的值。

我不确定 Microsoft 在哪里列出了实现定义行为的选择,但显然他们在这里选择了第一个选项。

ECMA-334 的附录 B 中列出了这种和其他实现定义或未定义的行为。 上面的规范草案是最近更新的,但似乎缺少这个附件。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...