Checked and unchecked (C# Reference)

C# statements can execute in either checked or unchecked context. In a checked context, arithmetic overflow raises an exception. In an unchecked context, arithmetic overflow is ignored and the result is truncated by discarding any high-order bits that don't fit in the destination type.

Console.WriteLine(int.MaxValue);           // 2147483647
Console.WriteLine($"0x{int.MaxValue:X}");  // 0x7FFFFFFF

Console.WriteLine(unchecked (int.MaxValue+1));          // -2147483648
Console.WriteLine($"0x{unchecked (int.MaxValue+1):X}"); // 0x80000000
Console.WriteLine(int.MinValue);                        // -2147483648
Console.WriteLine($"0x{int.MinValue:X}");               // 0x80000000

// Create overflow using compile-time constants:
// CS0220: The operation overflows at compile time in checked mode
// Console.WriteLine(checked (int.MaxValue+1));

try {
    checked 
    {
        var number = 1 + int.MaxValue / 2;
        number += number;
    }
} catch (OverflowException e)
{
    Console.WriteLine("This operation overflows at runtime in checked mode.");
}

In checked mode, any constant expression that overflows or underflows generates a compiler error. Any expression that overflows at runtime throws an System.OverflowException. In unchecked mode, it wraps from the maximum value to the minimum value.

The following operations are affected by the overflow checking:

  • Expressions using the following predefined operators on integral types:

    ++, --, unary -, +, -, *, /

  • Explicit numeric conversions between integral types, or from float or double to an integral type.

Beginning with C# 11, you can define a checked variant for operators that are affected by overflow checking. If you define a checked operator, you must also defined an operator without the checked keyword. For more information on checked and unchecked operators, see the article on Arithmetic operators.

If neither checked nor unchecked is specified, the default context for non-constant expressions (expressions that are evaluated at run time) is defined by the value of the CheckForOverflowUnderflow compiler option. By default the value of that option is unset and arithmetic operations are executed in an unchecked context.

For constant expressions (expressions that can be fully evaluated at compile time), the default context is always checked. Unless a constant expression is explicitly placed in an unchecked context, overflows that occur during the compile-time evaluation of the expression cause compile-time errors.

See also