Monday, August 9, 2010

Checking Overflow in C#

When you use value type in your application for arithmetic operations, you will need to check the boundaries of data types after the operation completes every time i.e., have to ensure the value of data type does not exceeds the MaxValue of the data type, Overflow does not occur.Else you will get overflow Exception at runtime.

Different languages treat this overflow in different Manner( C, C++ does not throw overflow exception rather wrap up the value, MS Visual Basic throws the Overflow Exception by default)
Whereas  .Net does not check for the overflow exception until we explicitly we tell the CLR to check for Overflow Exception. By Default Overflow check is set off .
Let's see an Example :
{              
      short val = 32767;
       val =  (short)(val + 40000);
 }

In above code, we try to add constant value to Val variable of short data type and error was expected when i ran  the application. But Surprise, it runs with no Exception
But Why ?? Let's look depth how CLR encounter the Corresponding IL instructions.CLR has two different versions of IL instructions for Arithmetic operations such as Add, Multiple, Subtract and
etc.


Add          :       Add (), Add.ovf ()  
Subtract    :       Sub (), Sub.ovf ()   
Multiply     :      Mul (), Mul.ovf ()    
Convert     :      Conv (), Conv.ovf ()

The Add Method which adds two value but it performs no overflow checking. And the another method Add.Ovf() which does the same operation, but it checks for overflow.
The IL code generated by compiler using the versions of the add, subtract, multiply, and conversion instructions that dont include overflow checking by default. So the code runs faster but developers
must be assured that overflows wont occur at runtime and causing the running program to get terminated.
 

How to intimate the C# compilers that OVF checking instructions should generated when we compile the program ?

.Net framework offers the solution in three ways and you can choose appropriate one as your require.
1.  Using Checked Switch in Compiler/ VS command line parameter
2.  Using Checked/Unchecked Operators
3.  Using Checked/Unchecked Statement

Checked Switch :
This is kind of Global switch if it is set on, where the compiler will understand and generate code that has the overflow-checking versions of the add, subtract, multiply, and conversion IL instructions when you compile your project.

The disadvantage is the code executes a little slower because the CLR is checking these operations to determine whether an overflow occurred. If an overflow occurs, the CLR throws an Overflow Exception.

This switch can be set on using Visual studio, Go To Project properties, click advanced tab in BUILD section. Now you have to enable the option 'Check for Arithmetic overflow/underflow'.
Look at the fig below :
This option is helpful when you want to enable/disable the Overflow-checking at project level.
Checked/ Unchecked Operators :
What if a programmer wants to enable/disable this overflow checking at only particular code region not at project level ? Here we go..
You can use Checked / Unchecked operators, which does the same operation as explained above. when compiler encounter these operators, compiler will generate appropriate version with overflow checking IL instructions instead of normal code to execute.

{
        short val = 32767;
        val =  Checked((short)(val + 40000));
        val =  UnChecked((short)(val + 40000));
} 
Since the Checked keyword is used in first statement, it performs overflow-checking and the Overflow exception will be thrown at runtime.The second statement does not perform overflow-checking and just ignores overflow and wrap up the value of data type.

In addition to Checked Operators, C# provides Checked/Unchecked Statement. The statement cause all expressions within a block to be checked or unchecked.
E.g :
Checked
{
                short val = 32767;
                val =  (short)(val + 40000);
                .....
                .....        
}

Let's see how C# compiler chooses the versions of instruction using sample C# code which checks for overflow and will have look at corresponding IL code using .Net Reflector


In the following sample, there are two methods which adds passed two param value and return the sum of those values. But one of the method which checks for over flow and another method
(AddValueWithNoOverflowCheck) ignores the over flow check.
Add Method with Checked Statement




Add Method With no checked Statment










 And the following images/snapshot are correspondng IL instructions of above code.

 

IL Code Of  Add Method which has Checked Statment
  

IL Code of Add Method which does not Check Overflow
If you see, you can find add.ovf and Conv.ovf IL instructions are generated inside a method body which is using Checked Statement. And simply add IL instruction is generated inside a method body which is using NOT using Checked Statement

Note :  
1. If you have multiple overflow checks in your code, the code will execute little slow. Because the CLR is monitoring the arithmetic operations whether overflow has occurred.But still it is recommend to you use checked operators and use only where it is required.

2. Calling a method (which perform some Arith. operations) inside Checked/unchecked statement will not have any impact as the code block which contains.

Monday, May 31, 2010

C# Data types

C# Primitive Data types :

Any data types directly supported by the compiler are called primitive types. Primitive types map directly to types that exist in the base class library.

These basic data types are used across programming language compilers regardless of managed code or unmanaged code, since it is essential to meet needs of storing the basic data(Numeric, character, Bool) in application development.

Let us see Primitive Data types of C# :























The CLR supports two different types
  •    Value Type
  •    Reference Type  
Value Type :

The variable representing the instance doesn’t contain a pointer to an instance; the variable contains the fields of the instance itself. Value type instances are usually allocated on a thread’s stack

Value types are derived from System.ValueType

1. Value types holds the value itself and values are allocated in stack.

2. Being represented in two forms (boxing & unboxing).

3. You can't create new value type which derives from any of the System.ValueType, because all the ValueType in framework is sealed.

4. Need not to use 'New' Keyword explicitly, if you want to use the default constructor of value type then use 'New' keyword.

Ex:-
int i = 5; //value is 5
int i = new int(); // value is 0
Here Default constructor of System.int32 type will assign the 0 as default value to the variable.

5. Types are declared using struct keyword are always ValueTypes.

Note :
Ultimately System.ValueType is derived from System.Object, that is why both types share common methods (ToString, GetType, GetHashcode). However in ValueType, Equals and GetHashCode are overridden for specific value implementation.

Reference Type :

The variable which holds reference (address)to object which is allocated in heap rather having object as value itself called reference types.

Following are examples of reference types.

"System.String, System.Delegate, System.Exception, System.Object"

And the types which are all derived from System.Object called reference Types except System.ValueTypes.

1. Reference type variable holds the address of object allocated in heap.

2. Stored in heap and managed by GC.

3. Attempting to use a null reference type variable causes a NullReferenceException exception. Indicating that the reference type variable doesn't currently point to a valid object.

4. Instance of the reference type must be initiated using 'New' keyword. The new keyword returns a reference to the object allocated on the heap, not the actual object itself.
But the reference variable is stored on the Thread stack for further use in your application.

5. Types are declared using class are reference types

Tweaks :

if value of the reference variable copied to another variable, then both of them points to one object which is allocated on heap.


The obj1 And obj2 Reference type variables are having same address as pointing to single object in heap. Operation on either of variable's data (object on heap) make impact on the other one.

In case of ValueType variable, the data will be copied to another variable. Both of them have separate copies.


Now i and j ValueType variables hold separate copies of data. Manipulating the variable j's value will not impact on variable i.

Thanks for reading.. Catch you in next post.

Sunday, May 2, 2010

A zen Story

This is my first post in this blog, so i thought let me start with some good self motivational and inspiration zen stories before get into .net programming :-)

you would have read many stories, but the following are most inspired me.
Hope you also like it.

Time To Learn
=============

A young but earnest Zen student approached his teacher, and asked the Zen Master:
"If I work very hard and diligent how long will it take for me to find Zen."
The Master thought about this, then replied, "Ten years."
The student then said, "But what if I work very, very hard and really apply myself to learn fast -- How long then ?"
Replied the Master, "Well, twenty years."
"But, if I really, really work at it. How long then ?" asked the student.
"Thirty years," replied the Master.
"But, I do not understand," said the disappointed student. "At each time that I say I will work harder, you say it will take me longer. Why do you say that ?"
Replied the Master," When you have one eye on the goal, you only have one eye on the path."

A cup of tea
============
Nan-in, a Japanese master during the Meiji era (1868-1912), received a university professor who came to inquire about Zen.
Nan-in served tea. He poured his visitor's cup full, and then kept on pouring.
The professor watched the overflow until he no longer could restrain himself. "It is overfull. No more will go in!"
"Like this cup," Nan-in said, "you are full of your own opinions and speculations. How can I show you Zen unless you first empty your cup?"


Good is n't it ?? :-)

Catch you in next post.