Search code examples
c#unchecked

System.OverflowException in unchecked block of C#


If I pass Int32.MinValue and -1 into the Divide() method, I get a System.OverflowException despite the block happening in an unchecked block.

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

This is surprising to me - unless I've read the documentation for checked / unchecked incorrectly, I'd expect it to just give me an overflowed output (since Int32.MinValue / -1 = 2^31 = Int32.MaxValue + 1, I was expecting an overflow to a value of Int32.MinValue). Instead it threw an OverflowException.

Here's a DotNetFiddle showing the issue.


Solution

  • From the C# draft specification on integer division:

    If the left operand is the smallest representable int or long value and the right operand is -1, an overflow occurs. In a checked context, this causes a System.ArithmeticException (or a subclass thereof) to be thrown. In an unchecked context, it is implementation-defined as to whether a System.ArithmeticException (or a subclass thereof) is thrown or the overflow goes unreported with the resulting value being that of the left operand.

    I'm not sure where Microsoft lists its choices for implementation-defined behavior, but apparently they chose the first option here.

    This and other implementation-defined or undefined behavior is listed in Annex B of ECMA-334. The draft specification above is updated more recently, but it seems to lack this annex.