Thursday, March 22, 2012

Exception handling in C++!!

              C++ supports exception handling feature. It will be implemented using try, throw and catch keywords.This is used to exit the application in a proper way after getting the errors like divided by zero or finding the square root of a negative no. or fatal errors. This will throw an error message depending on the error codes.
 
           In C++, exception handling works in such a way that, it looks for the possible errors in try block and if error or exception occurs, it will throw the error. And thrown error in try block will be handled in catch block. Throwing an exception is just jumping the control flow to the catch block when error occurs. After throw statements never execute when exception occurs. Below is simple example.

#include<iostream>
using namespace std;

int main()
{
    try
    {
        throw 3;
    }
    catch(int i)
    {
        cout<<"caught value "<<i<<endl;
    }

    return 0;
}


OutPut:
caught value 3


The above sample code excute the try block, there it throw the numeric value three, so it looks for the corresponding catch block for int , so it displays the message.
Another example by throwing string:

Sampel code for throwing string:
#include<iostream>
#include<math.h>
using namespace std;

main()
{
    try
    {
        int num;
        cout<<"enter the number for square root"<<endl;
        cin>>num;
        if(num<0)
        {
            throw "can't find square root for negative numbers";
        }
        cout<<"sqrt is "<<sqrt(num)<<endl;
    }
    catch( char const *str)
    {
        cout<<str<<endl;
    }
}

Output:
enter the number for square root
4
sqrt is 2

enter the number for square root
-3
can't find square root for negative numbers


Above sample code in try block excutes and check for the condition and throws a constant string when negative no. occurs. After throwing, it looks for the corresponding catch block and displays the messages.

Till now we have seen the example of using throw with in the try block. But most of the cases are different, where throwing an exception is not in try block. So what exactly compiler does is that, it will check for immidiate catch block , if not , it will send to its caller function, there it checks for the catch block and goes on till it reaches corresponding catch block or till it reaches main function. This process is called stack unwinding.

Example for stack unwinding:

#include<iostream>
using namespace std;

void fun2()
{
    throw "throwing exception in func2\n";
}

void fun1()
{
    cout<<"in fun1()\n";
    try
    {
        fun2();
    }
    catch(char *)
    {
        cout<<"exception caught in fun1\n"<<endl;
    }
}
void display()
{
    cout<<"in display()\n";
    fun1();
}
main()
{
    try
    {
        cout<<"in main function\n";
        display();
    }
    catch(char const*str )
    {
        cout<<"exception caught in main \" "<<str<<"\""<<endl;

    }
}

OutPut:
in main function
in display()
in fun1()
exception caught in main " throwing exception in func2"

In the above sample code, main function calls display() and it calls fun1() and it calls fun2(), fun2() throws exception with constant string, but fun2() don't have catch block, so it returns to its caller fun1(), fun1() is having catch() block, but it is not a constant string , so it returns its caller fun(), fun() don't have catch block, it returns to its caller main(). main has its corresponding catch block, so exception caught in main function.


What happens if no matching catch block: Generally compiler looks for the matching catch block. If there is no catch block, application terminates with a error message depending on the compiler. In GNU C++ compiler the error message is "terminate called after throwing an instance of" for no matching catch for exceptions. To avoid such cases C++ provides a default catch block with (...) three consecutive dots in a catch. If you have no idea what to throw, just use default throwing three dots (...) similar to default catch.

Sample code for no matcing catch block:

#include<iostream>
using namespace std;

int main()
{
    try
    {
        throw 3;
    }
    catch(char )
    {
        cout<<"caught exception "<<endl;
    }

    return 0;
}

OutPut:
terminate called after throwing an instance of 'int'
Aborted

In the above code, try block throwing int value, but there is no catch block to handle int value, so it will abort the process with the error message as shown in the output.
Sample code for default catch block:
#include<iostream>
using namespace std;

int main()
{
    try
    {
        throw 3;
    }
    catch(...)
    {
        cout<<"caught exception "<<endl;
    }

    return 0;
}
OutPut:
caught exception

In above samle code, try block throws int exception, but there is no int catch block,there is a default catch block to handle any exception.

No comments:

Popular Posts