【问题标题】:System.OverflowException in unchecked block of C# [duplicate]未经检查的 C# 块中的 System.OverflowException [重复]
【发布时间】:2021-02-05 16:59:48
【问题描述】:

如果我将 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 显示问题。

【问题讨论】:

    标签: c# unchecked


    【解决方案1】:

    From the C# draft specification on integer division:

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

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

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

    【讨论】:

    • 答案很清楚。您的回答让我尝试查看 DotnetFiddle 支持的任何其他编译器中的行为是否发生了变化。它们都产生相同的结果。不过,从选中的块中弹出 OverflowException 有点违反直觉。
    猜你喜欢
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多