Silent Overflow in CLR

Note: This blog post transferred from my OLD BLOG and was originally posted in 2007.

One of the things you want to avoid in your arithmetic operations on primitive types is the Silent Overflow , for example :

 
as you can see the value of Y is not the desired value , this is because the illegal operation on 2 different primitive types . what just happened is known as Silent Overflow , this kind of silent overflow handled in each programming language in a different way , language like C# consider this kind of overflow is not an error that’s why it allow it by default . other language like VB always consider this kind of overflow as an error and throw exception .
 
What’s matter here is the desired behavior the program need , in most scenarios you will need this kind of silent overflow not to happen in your code or you will get strange unexpected behaviors .
 
Fortunately the common language runtime (CLR) offers IL instructions that make it very easy task for each .Net language compiler to choose the desired behavior
 
add adds two values together, with no overflow checking.
add.ovf adds two values together.However,it throws System.OverflowException if an overflow occurs.
sub subtraction with no overflow checking.
sub.ovf subtract two values , throw System.OverflowException if an overflow occurs.
mul multiplication with no overflow checking.
mul.ovf multiply two values , throw System.OverflowException if an overflow occurs.
conv convert value with no overflow checking.
conv.ovf convert value  , throw System.OverflowException if an overflow occurs.

Now let’s take a closer look on how C# compiler take advantage of this set of IL instructions . first, by default C# compiler doesn’t use overflow checking instructions to run the code faster , this means that the add,subtract,multiply and conversion instruction in C# will not include overflow checking

as you can see the C# compiler generated IL uses the add instruction as it the default behavior for C# to generate silent overflow , generally you can turn that off by compile your code using the /checked+ compiler switch , which tell the C# compiler to uses the safe version of the add with overflow check , add.ovf which will prevent this kind of silent overflow and throw OverflowException if overflow occur.

Sometimes you don’t want to turn the overflow globally for the whole application , rather you want to enable it only in some places in your code that’s when checked and unchecked C# operators come into the picture .

Simply checked operator tells the C# compiler to use the safe IL instruction for this operation , and the unchecked use the normal IL instructions (which is the normal behavior in C#).

now let’s modify our simple example to use the checked operator :

using the checked operator in our example generates OverflowException because the C# Compiler generated the IL using the safe add instruction add.ovf as you can see .

C# also offers checked and unchecked statements for wider scope of overflow checking but still determined by the developer inside his/her code .

same result as you can see , OverflowException has been thrown and the generate IL uses add.ovf , just the IL get larger because the C# compiler generated more (no operation instruction nop) which you can get ride of by generating more optimized version of your app.

Hope this Helps,

Ahmed

Advertisements