An Exception is a condition
that is caused by a run-time error in the program. There are two types of bugs which are: Logical Errors and Syntax
errors
- Syntax errors occur due to poor understanding of the language itself.
The purpose of exception handling is to provide a means to detect and
report "Exception Circumstances" so that appropriate action can be
taken.
The mechanism incorporates a separate error handling code that
performs the following tasks:
- Finding the problem (Hit the exception)
- Inform that an error has occurred (Throw the exception)
- Receive the error information (Catch the exception)
- Take corrective actions (Handle the exception)
- Synchronous Exceptions are the errors such as "Out-of-range index", "Overflow".
- Asynchronous Exceptions are errors that are caused by events beyond the control of the program.
- One to detect errors and throw the eception
- Other to catch the exception and take appropriate actions
Syntax for error handling Code:
Try Block
|
Detects
and throws an exception
|
Exception Object
Catch Block
|
Catches
and handles an exception
|
Exception handling is build
upon three keywords
- try
- throw
- catch
Throw: When an exception is
detected, it is thrown using throw statement in the try block.
Catch: Catch block is defined by the keyword catch. It catches the
exception thrown by the try block and handles it appropriately.
E.g.:
-------------
-------------
try
{
statements; //generates an exception
}
catch(exception_type
arg)
{
statements; //processes an exception
}
|
The try block can have one or more statements that could generate an
exception.
The catch block can have one or more statments that are necessary to
process the exception.
If the try block throws an exception and it matches with the exception
type in the catch statement, then catch block is executed for handling the
exception.
If they do not match, the program is aborted with the help of abort()
function which is invoked by default.
When no exception is detected and thrown, the control goes to the
statement immediately after the catch block i.e., the catch block is skipped.
E.g.: Try Block throwing an exception
|
int main()
{
int
a, b;
cout<<"Enter
the values of a and b\n";
cin>>a>>b;
int
x=a-b;
try
{
if(x!=0)
{
cout<<"Result
(a/x) = "<<a/x;
}
else //There is an exception
{
throw(x); //Throws int
object
}
catch(int
i)
{
cout<<"Exception
Caught : x = "<<x;
}
}
cout<<"\nEnd";
return0;
}
|
Output
First Run Second
Run
Enter
the values of a and b
20
20
Exception
Caught : x = 0
End
|
Enter
the values of a and b
20
15
Result
(a/x) = 4
End
|
This program detects and catches a division-by-zero problem. The
output of first run shows a successful execution. When no exception is thrown,
the catch block is skipped and execution resumes with the first line after the
catch. But in the seond run, the denominator x becomes zero and therefore,
division by zero situation occurs. This exception is thrown by using object x.
Functions Invoking Exceptions
Exceptions are thrown by functions that are invoked from within the
try block. The point which at which throw is executed is called the Throw
Point. Once an exception is thrown to the catch block, control can not return
to the throw point.
Throwing Mechanism
When an exception that is desired to be handled is detected, it is
thrown using the throw statement in on of the following form:
throw(exception);
OR
throw exception;
OR
throw; //used for re-throwing an
exception
|
When an exception is thrown, it will be caught by the catch statement associated with the try block. That is the control exits the current try block and is transferred to the catch block after that try block.
Catch Mechanism
The code for handling exceptions is included in catch blocks
catch(type arg)
{
//statements
for managing exceptions
}
|
Here type indicates the type of exception that this catch block handles. The perameter arg is an optional parameter name.
The catch statement catches an exception whose type matches with the type of catch argument. When it is caught, the code in the catch block is executed.
Multiple Catch Statments
Syntax:
|
E.g.:
|
try
{
//try
block
}
catch(type
1 arg)
{
//catch
block 1
}
catch(type
2 arg)
{
//catch
block 2
}
----------------------
----------------------
catch(type
N arg)
{
//catch
block N
}
|
void test(int x)
{
try
{
if(x==1)
throw x; //int
if(x==0)
throw 'x' //char
if(x==-1)
throw x //double
cout<<"\nEnd
of try block";
}
catch(char
c) //catch 1
{
cout<<"\nCought
a character\n\n";
}
catch(int
m) //catch 2
{
cout<<"\nCought
a integer\n\n";
}
catch(double
d) //catch
3
{
cout<<"\nCought
a double\n\n";
}
cout<<"\nEnd
of try-catch system";
}
int main()
{
cout<<"Testing
multiple catches\n\n";
cout<<"x==1";
test(1);
cout<<"x==0";
test(0);
cout<<"x==-1";
test(-1);
cout<<"x==2";
test(2);
return
0;
}
|
When an exception is thrown, the exception handlers are searched in an order for an appropriate match. After executing with the match handler, the control goes to the first statement after last catch block for that try.
Output
|
Testing multiple catches
x==1
Cought a character
x==0
Cought a integer
x==-1
Cought a double
x==2
End of try block
End of try-catch system
|
When try block does not throw any exception and it completes normal execution, control passes to the first statement after the last catch handler.
Catching All Exceptions
It is not possible to determine all possible type of exceptions and
therefore no independent catch handler can be designed to catch them.
Syntax:
|
E.g.: Catch All Exceptions
|
catch(....)
{
//statements
for processing all exception
}
|
void test(int x)
{
try
{
if(x==1)
throw x; //int
if(x==0)
throw 'x'; //char
if(x==-1)
throw x; //double
}
catch(....) //Catch
all
{
cout<<"Caught
an Exception\n";
}
}
int
main()
{
cout<<"Testing
Generic Catch\n;
test(-1);
test(0);
test(1);
return
0;
}
|
Output
|
Here all throws are caught by the catch(....) statement
|
Testing Generic Catch
Caught an Exception
Caught an Exception
Caught an Exception
|
Re-throwing an Exception
When the catch block throws an exception, it is termed as re-throwing
an Exception. In such a case, throw is invoked without any argument.
Syntax: throw;
This causes the current exception to be thrown to the next enclosing
try-catch sequence and is caught by the catch statement listed after that
enclosing try block.
A catch handler itself may detect and throw an exception. The
exception thrown will not be caught by any catch statement of that group. It
will be passed to the next outer try-catch sequence for processing.
E.g.:
|
void divide(double x, double y)
{
cout<<"Inside
function";
try
{
if(y==0.0)
throw y;
else
cout<<"\nDivision = "<<x/y;
}
catch(double)
{
cout<<"\nCaught
double inside function";
throw;
}
cout<<"\nEnd
of function\n\n";
}
int
mian()
{
cout<<"Inside
main\n";
try
{
divide(10.5,
2.0);
divide(20.0,0.0);
}
catch(double)
{
cout<<"\nCaught
double inside main";
}
cout<<"\nEnd
of main;
return
0;
}
|
Output
|
Inside main
Inside function
Division = 5.25
End of function
Inside function
Caught double inside function
Caught double inside main
End of main
|
Specifying Exceptions
It is done to restrict a function to throw only certain specified
exception. This is achieved by adding a throw list clause to the function
definition.
General form of using Exception Specification:
|
type function(arg-list) throw (type-list)
{
--------------
--------------
function body
--------------
}
|
Here type-list specifies the type of exceptions that may be thrown.
Throwing any other type of exception will cause abnormal program termination.
To prevent function from throwing any exception the type-list is kept empty. E.g.: throw();.
E.g.:
|
Output
|
void test( int x) throw(
int, double)
{
if(x==1) throw x; //int
else
if(x==-1) throw 1.0 //double
cout<<"\nEnd
of function block";
}
int main()
{
try
{
cout<<"Testing
throw restrictions\n\n";
cout<<"x==1";
test(1);
cout<<"x==-1";
test(-1);
cout<<"x==2";
test(2);
}
catch(int
m)
{
cout<<"\nCaught
an integer\n\n";
}
catch(double
d)
{
cout<<"\nCaught
an double\n\n";
}
}
|
Testing throw restrictions
x==1
Caught an integer
x==-1
Caught an double
x==2
End of function block
|