首页 > 解决方案 > System.OverflowException 在 C# 的未检查块中

问题描述

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

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

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

这是一个显示问题的DotNetFiddle

标签: c#unchecked

解决方案


来自关于整数除法的 C# 草案规范

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

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

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


推荐阅读