Cpp_UNIT-5
Cpp_UNIT-5
EXCEPTION HANDLING
Exceptions are run-time anomalies or abnormal conditions that a program encounters during its
execution.
Exception : An exception is an abnormal condition that arises in a code sequence at run-time. In
other words, an exception is a run-time error.
Exception Handling : Handling the exception explicitly by the programmer, so that all the
statements of the program are executed is called exception handling.
Benefits of exception handling:
Following are main advantages of exception handling over traditional error handling.
1) Separation of Error Handling code from Normal Code: In traditional error handling codes,
there are always if else conditions to handle errors. These conditions and the code to handle
errors get mixed up with the normal flow. This makes the code less readable and maintainable.
With try catch blocks, the code for error handling becomes separate from the normal flow.
2) Functions/Methods can handle any exceptions they choose: A function can throw many
exceptions, but may choose to handle some of them. The other exceptions which are thrown, but
not caught can be handled by caller. If the caller chooses not to catch them, then the exceptions
are handled by caller of the caller.
In C++, a function can specify the exceptions that it throws using the throw keyword. The caller
of this function must handle the exception in some way (either by specifying it again orcatching
it)
3) Grouping of Error Types: In C++, both basic types and objects can be thrown as exception.
We can create a hierarchy of exception objects, group exceptions in namespaces or classes,
categorize them according to types.
1 : try block : The programmer should observe the statements in his program. Where there maybe
a possibility of exceptions. Such statements should be written inside a try block.
Syntax : try
{
statements;
}
A try block can throw more than one exception. There should be a catch block to handle
the exceptions thrown by try block
2 : throw : When an exception is detected , it is thrown using a throw statement in the try block
Syntax : try
{
statements; throw exception;
}
Where ‘exception ‘ is an object of any type including a constant.
3: catch block: The catch block handles an exception thrown by the try block. It defines actionsto
be taken when a runtime error occurs.
Syntax: catch (type arg)
{
statements;
}
try
throw exception;
}
catch( type arg)
{
When the try block throws an exception then the control leaves the try block and goes to the
catch block. Exceptions are nothing but the objects that are used to transmit information about a
problem. If exception thrown matches the argument type in the catch block then the catch block is
executed which reports the error. If exception thrown does not match the argument type in the
catch block then the program is aborted by using function abort() .
If no exception is thrown from the try block then the catch block is skipped and control goes
immediately to the next statement following the catch block.
void main()
{
int a,b,c;
cout<<"enter a and b values";cin>>a>>b;
try
{
if(b==0) throw b;else
cout<<"c value is"<<a/b;
}
catch(int x)
{
cout<<"Error:Divide by zero Exception";
}
}
Multiple catch statements : A try block may throw more than one exceptions where a catchblock
can handle only one exception at a time.
Syntax : try
{
catch(type1 arg)
{
// catch block1;
}
catch(type2 arg)
{
// catch block2;
}
catch(typeN arg)
{
// catch blockN;
}
When an exception is thrown these catch blocks are searched in order for an
appropriate match. In this search the first handler i.e the catch block that matches the exception
thrown is executed. If none of catch blocks match then the control goes to the statement
immediately after the last catch block.
catch(int i)
{
cout<<"An Integer caught";
}
catch(char c)
{
cout<<"An character caught";
}
catch(double d)
{
cout<<"An double caught";
}
}
void main()
{
int a;
cout<<"Enter a value:"<<endl; cin>>a;
fun(a);
}
Catch All Exception: A catch block can also handle all the exceptions. Such a catch block that
handles all exceptions can be defined using ellipses(…) in the catch statement as follows.
Syntax : catch( … )
{
}
#include<iostream.h> void fun(int x)
{
try
{
if(x==0)throw x; //throws integer value if(x==1) throw 'x'; //throws character value if(x==-1)
throw 1.0; //throws double value
}
catch(...)
{
cout<<"caught an exception";
}
}
void main()
{
int a;
cout<<"Enter a value:"<<endl; cin>>a;
fun(a);
}
Exception specification
A dynamic exception specification follows the declaration of a function, appending throw specifier
to it. For example:
return 0;
}
OUTPUT:
f1() Start
Standard exception: 100
The new exception can be defined by overriding and inheriting exception class functionality. C++
Let's see the simple example of user-defined exception in which std::exception class is used to
define the exception.
The C++ Standard library provides a base class specifically designed to declare objects to be
thrown as exceptions. It is called std::exception and is defined in the <exception> header. This
class has a virtual member function called what that returns a null-terminated character sequence
(of type char *) and that can be overwritten in derived classes to contain some sort of description
of the exception.
In above example what() is a public method provided by the exception class. It is used to return
the cause of an exception.
Exception Objects:
All exceptions thrown by components of the C++ Standard library throw exceptions derived from
this exception class. These are:
exception description
bad_alloc thrown by new on allocation failure
bad_cast thrown by dynamic_cast when it fails in a dynamic cast
bad_exception thrown by certain dynamic exception specifiers
bad_typeid thrown by typeid
bad_function_call thrown by empty function objects
bad_weak_ptr thrown by shared_ptr when passed a bad weak_ptr
Also deriving from exception, header <exception> defines two generic exception types that canbe
inherited by custom exceptions to report errors:
exception description
logic_error error related to the internal logic of the program
runtime_error error detected during runtime
An example where standard exceptions need to be checked for is on memory allocation:
// bad_alloc standard exception
#include <iostream>
#include <exception>
using namespace std;
int main () {
try
{
int* myarray= new int[1000000];
}
catch (exception& e)
{
cout << "Standard exception: " << e.what()
<< endl;
}
return 0;
}
The exception that may be caught by the exception handler in this example is a bad_alloc.
Because bad_alloc is derived from the standard base class exception, it can be caught (capturing
by reference, captures all related classes).
Rethrowing An Exception:
Re throwing an exception from within an exception handler can be done by calling throw, by
itself, with no exception. This causes current exception to be passed on to an outer try/catch
sequence. An exception can only be rethrown from within a catch block. When an exception is
rethrown, it is propagated outward to the next catch block.
Example:
#include<iostream>
using namespace std;
void MyHandler()
{
try
{
throw “hello”;
}
catch (const char*)
{
cout <<”Caught exception inside MyHandler\n”;
throw; //rethrow char* out of function
}
}
int main()
{
cout<< “Main start”;
try
{
MyHandler();
}
catch(const char*)
{
cout <<”Caught exception inside Main\n”;
}
- Thus, exception rethrown by the catch block inside MyHandler() is caught inside main();
//rethrowing an exception
#include<iostream>
using namespace std;
void f1()
{
cout<<"f1 started"<<endl;
try{
throw 100;
}
catch(int x)
{
cout<<"exception handled in f1 "<<x<<endl; throw 50;
}
cout<<"f1 ended"<<endl;
}
int main()
{ try{
f1();
catch(int y)
{ cout<<"exception handled in main "<<y<<endl
}
}
Stack Unwinding in C++
The process of removing function entries from function call stack at run time is called Stack
Unwinding.
when an exception occurs, the function call stack is linearly searched for the exception handler,
and all the entries before the function with exception handler are removed from the function
call stack. So exception handling involves Stack Unwinding if exception is not handled in same
function (where it is thrown).
For example, output of the following program is:
#include <iostream>
// Another sample function f3() that calls f2() and handles exception thrown by f1()
void f3() {
cout<<"\n f3() Start ";try {
f2();
}
catch(int i) {
cout<<"\n Caught Exception: "<<i;
}
cout<<"\n f3() End";
}
}
OUT PUT:
f3() Start f2() Startf1() Start
Caught Exception: 100f3() End