C# Language checked, unchecked


The checked and unchecked keywords define how operations handle mathematical overflow. "Overflow" in the context of the checked and unchecked keywords is when an integer arithmetic operation results in a value which is greater in magnitude than the target data type can represent.

When overflow occurs within a checked block (or when the compiler is set to globally use checked arithmetic), an exception is thrown to warn of undesired behavior. Meanwhile, in an unchecked block, overflow is silent: no exceptions are thrown, and the value will simply wrap around to the opposite boundary. This can lead to subtle, hard to find bugs.

Since most arithmetic operations are done on values that are not large or small enough to overflow, most of the time, there is no need to explicitly define a block as checked. Care needs to be taken when doing arithmetic on unbounded input that may cause overflow, for example when doing arithmetic in recursive functions or while taking user input.

Neither checked nor unchecked affect floating point arithmetic operations.

When a block or expression is declared as unchecked, any arithmetic operations inside it are allowed to overflow without causing an error. An example where this behavior is desired would be the calculation of a checksum, where the value is allowed to "wrap around" during calculation:

byte Checksum(byte[] data) {
    byte result = 0;
    for (int i = 0; i < data.Length; i++) {
        result = unchecked(result + data[i]); // unchecked expression
    return result;

One of the most common uses for unchecked is implementing a custom override for object.GetHashCode(), a type of checksum. You can see the keyword's use in the answers to this question: What is the best algorithm for an overridden System.Object.GetHashCode?.

When a block or expression is declared as checked, any arithmetic operation that causes an overflow results in an OverflowException being thrown.

int SafeSum(int x, int y) {
    checked { // checked block
        return x + y; 

Both checked and unchecked may be in block and expression form.

Checked and unchecked blocks do not affect called methods, only operators called directly in the current method. For example, Enum.ToObject(), Convert.ToInt32(), and user-defined operators are not affected by custom checked/unchecked contexts.

Note: The default overflow default behavior (checked vs. unchecked) may be changed in the Project Properties or through the /checked[+|-] command line switch. It is common to default to checked operations for debug builds and unchecked for release builds. The checked and unchecked keywords would then be used only where a default approach does not apply and you need an explicit behavior to ensure correctness.