So, some of you may not know about this keyword at all, but at one point in your life you may find out and feel that it will be useful to use it when you are doing mathematical operations in your code. Let’s start by discussing what this keyword provides. According to Microsoft documentation, the checked keyword is provided to explicitly enable arithmetic overflow for integer mathematical operations. In the past we have discussed how arithmetic overflows can cause problems and unexpected outcomes from our code. A prime example we mentioned is why Ghandi was a nuclear asshole in Civilization

Now the C# compiler itself can recognize arithmetic overflows when it comes to constant values and variables. For example the following line of code

int y = int.MaxValue + 100;

will not compile as it is obvious from the constant values that an arithmetic overflow will occur.

On the other hand the following lines of code

int x = 100; int y = int.MaxValue + x;

will compile normaly, as the value of x is not clearly visible at compile time.

This will lead to an overflow and end up as a negative value.

The C# compiler provides us with the checked keyword. So if we enclose our code inside a checked keyword block like the following

checked { int x = 100; int y = int.MaxValue + x; }

An OverflowException will be thrown at runtime.

Given that checked adds a prossesing overhead the C# compiler also provides the unchecked keyword in cases where the developer wants to not perform any checks on some parts of a checked block but cannot re-order them to be removed from the checked block

And this is where it all falls apart. Even the C# compiler is aware that adding the checked keyword is adding a processing overhead, so why would you?

If any part of your code may possibly overflow and it is not part of your contract (e.g. cheksum validations, hashing and cryptography often rely on overflowing)

probably you should but, if you are aware the possible range of the values you are about to perform mathematical operations on, will definitely not overflow, then using checked actually slows down your processing time.

For example let’s see the following code example

private static void Main(string[] args) { Stopwatch ss = new Stopwatch(); ss.Start(); for (int i = 0; i < 10000; i++) { for (int j = 0; j < 10000; j++) { var x = multiply(i, j); } } ss.Stop(); Console.WriteLine($"Without checked {ss.ElapsedTicks}"); ss = new Stopwatch(); ss.Start(); for (int i = 0; i < 10000; i++) { for (int j = 0; j < 10000; j++) { try { var x = multiplyChecked(i, j); } catch (OverflowException) { } } } ss.Stop(); Console.WriteLine($"With checked {ss.ElapsedTicks}"); Console.ReadLine(); } private static int multiply(int i, int j) { return i * j; } private static int multiplyChecked(int i, int j) { return checked(i * j); }

The above piece of code shows that using checked adds a huge chunk of overhead to your code.

Running it a few times and averaging the results were the following

Without checked 318 975,7

With checked 2 070 000

So you can see that checked is actually 10 times slower than not using it at all. So yes, checked is something very useful in arithmetic operations, but adds a huge overhead to your code, so use it only if necessary.

Checked keyword also has a few more caveats that you need to be aware of as well.

Checked does not work with float or double value types

Checked is not required for divide by zero issues. A DivideByZeroException will be thrown regardless

Decimals also do not require the use of the checked keyword, they include overflow checking regardless

Checked and unchecked will only apply to the code enclosed inside that block For this we need to explain a bit more. If you are calling a method that is performing mathematical operations that may cause an overflow, the checked keyword will not help.

For example

int addTen(int i) { return i + 10; } void f() { checked { int i = addTen(int.MaxValue); } }

The above code will not throw any exception even though an overflow is guaranteed to happen. Checked only helps if an operation is happening inside the block. Any code that is being executed in a separate method will not be checked

That’s it. Hope all this new knowledge helps