Apparently my understanding of no checks vs unchecked vs checked was flawed. It was simple enough to write some simple tests to see overflow behavior in this fiddle.
The quick summary is this:
If running with no explicit checks
- If the compiler can easily and statically determine that code will overflow, there will be a compile error.
- If there is an overflow at runtime there will not be any overflow exceptions thrown.
If running explicitly unchecked
- The compiler will allow code that will obviously overflow
- No runtime overflow exceptions will be thrown
If running explicitly checked
- If the compiler can easily and statically determine that code will overflow, there will be a compile error.
- If there is an overflow at runtime a
System.OverflowException
will be thrown.
So... I guess the lesson from all of this is if you have some calculations that may overflow, and you care about overflow, it is very important to put that inside of a checked
block. If you have code that may overflow, and you don't care about overflow, apparently you can skip the unchecked block (unless your code will obviously overflow from a static analysis point of view).
The code from the fiddle is copied here as well for posterity.
using System;
public class Program
{
public static void Main()
{
var rand = new Random();
int test = 0;
//obscured enough that the compiler doesn't "know" that the line will produce an overflow
//Does not run explicitly as checked, so no runtime OverflowException is thrown
test = rand.Next(Int32.MaxValue-2, Int32.MaxValue) + 10;
//simple enough that the compiler "knows" that the line will produce an overflow
//Compilation error (line 16, col 10): The operation overflows at compile time in checked mode
//test = Int32.MaxValue + 1;
//Explicitly running as unchecked. Compiler allows line that is "known" to overflow.
unchecked
{
test = Int32.MaxValue + 1;
}
Console.WriteLine(test);
//Explicitly running as unchecked. Still no runtime OverflowException
unchecked
{
test = test - 10;
}
Console.WriteLine(test);
//Explicitly running as checked. System.OverflowException: Arithmetic operation resulted in an overflow.
checked
{
test = test + 10;
}
Console.WriteLine(test);
}
}