Often Unused Operators: checked and unchecked

From MSDN:
The checked keyword is used to explicitly enable overflow-checking for integral-type arithmetic operations and conversions.
By default, an expression that contains only constant values causes a compiler error if the expression produces a value that is outside the range of the destination type. If the expression contains one or more non-constant values, the compiler does not detect the overflow.

The unchecked keyword is used to suppress overflow-checking for integral-type arithmetic operations and conversions.
In an unchecked context, if an expression produces a value that is outside the range of the destination type, the overflow is not flagged.

Okay, so what the hell does this mean?
The C# compiler checks at compile time for overflow exceptions.
If you do:

int tooBig = 2147483647 + 10;

you get the error “The operation overflows at compile time in checked mode.” The problem arises when you use variables. Since a variable could be anything the compiler doesn’t check for overflows. If you do:

int ten = 10;
int tooBig = 2147483647 + ten;

your code will compile but the value of tooBig will be -2147483639. This is because default behavior of the runtime environment is to skip checking for overflows and your values just wrap.

So, what do you care?

Most likely you don’t. I’ll be honest. Chances are you’re not writing algoritms so important that if you overflow the world is going to come crashing down about you. Every once in awhile you do, however, come across some peace of critical software that may need to handle overflow exceptions. That is where the checked and unchecked operations come into play.

The problem is that checking every math operation for an overflow is slow. Okay, maybe slow is a bit much. It is, however, a couple of microseconds that you could be using on other things and it’s really slow if an overflow exception is thrown and you have to handle it. In math heavy operations and algorithms these few microseconds could add up to a lot of time so be sure that your code is critical enough that an overflow must be handled.

So, how do we fix this? We use the checked operation (in either the block or expression form).

//block
checked{
    int twenty = 10 + 10;
}
//expression
int thirty = checked(10 + 20);

This tells the compiler to check the numbers and if there is an overflow throw an overflow exception.

The opposite of the checked operator is unchecked:

//block
unchecked{
    int twenty = 10 + 10;
}
//expression
int thirty = unchecked(10 + 20);

This works just like the default behavior of not checking for overflows with variables. Since this is done automatically you probably won’t use this too often unless you start using the checked operator. The nice thing is that you can combine both checked and unchecked for the appropriate values.

unchecked
{
    int ten = 10;
    int tooBig = checked(2147483647 + ten);
    Console.WriteLine(i3);
}

yields an overflow exception being thrown since 2147483647 + ten overflows. Conversely,

checked
{
    int ten = 10;
    int tooBig = unchecked(2147483647 + ten);
    Console.WriteLine(i3);
}

results in a value of -2147483639 since the unchecked means the runtime environment to not check for overflow.

That’s all for now,
Brian

Comments (2)

  1. I’m going to need this in VB.NET

    • Brian

      Oddly enough VB acts the opposite of C# by automatically throwing overflow exceptions. I did a bit of googling around and can’t seem to find a VB equivalent for these. It seems like they only did this for C# since the default behavior is not to throw overflow exceptions and they wanted some way to allow you to do so if you wanted them short of doing a compile with a /Checked+ flag.
      You can see more on MSDN’s page for Int32.

Leave a Reply