Title: CS 204 Advance Programming Exception Handling in C
1CS 204 Advance Programming Exception Handling in
C
- Berrin Yanikoglu
- Yücel Saygin
- Some slides thanks to Hannu Laine
2Exceptions
- Good program is stable and fault tolerant.
- In a good program, exceptional (error)
situations must be handled. - Exceptions are unusual events (erroneous or not)
- They are detectable by either hardware or
software - They may require special processing
- Exception handler is part of the code that
processes an exception - Some examples for exceptions
- EOF is reached while trying to read from a file
- Division by 0 is attempted (result is
meaningless) - Array subscript is out of range
- Bad input
-
3Why exceptions?
- In traditional code, the following may be done in
error-prone situations - error values are returned from a function
- new or malloc() returns null for out of memory
- fopen() returns null when the file can not be
opened - a global error condition flag is set
- The programmer is then responsible for checking
these returned values
4Why exceptions?
- Example.
- if ((p malloc(sizeof(float)) NULL)
- //handle error
- if ( (f fopen(file.txt, r) ) NULL)
- //handle error
- This kind of error detection
- makes the program logic unclear.
- cannot be used to handle errors in constructors
(because they dont return a value). - user may not check the returned error
- errors must be handled immediately. The
application should decide how to act in error
situations. - Because of these drawbacks a new method to handle
error situations (exceptions) is developed in C.
5More advantages
Exception handling unwinds the stack. It means
that all objects that are allocated from the
stack in a failed block are released and their
destructors are called. Exception handling is
fully object oriented method (it is possible to
use polymorphic exception handling). It is
possible to separate the code needed fornormal
operation and for exception situations. It is
possible to decide at what level the exception is
handled.
6Exception Handling in C
7Basics of Exception Handling
8(No Transcript)
9Exception Handling Sample Code
Simple program to convert entered height (in cm)
into inches cout ltlt Enter height
cin gtgt height try if
(height gt 300) throw height
exceeds maximum if (height lt 0)
throw height below minimum cout
ltlt Inch equivalent ltlt ToInches(height)
catch(const char msg)
cout lt msg ltlt endl
10Three Keywords
- try identifies a code block where exception can
occur - throw causes an exception to be raised (thrown)
- catch identifies a code block where the
exception will be handled (caught) - try
- exception
- throw catch
-
11The fundamentals of exception handling
The normal code is put in a so called try
block. It means that we try to execute code
in the try block. If the system succeeds to run
the code, everything is fine. If or when
something goes wrong when code of try block is
executed, this code throws an exception object
and stops executing the code of try block
further. Another part of the code (the error
handling part) can catch the exception (object)
and make necessary actions needed in that error
situation. The exception object can contain
information about the exception, so that the
error handling part of the program can examine
the reason and make appropriate actions.
12How it works
- When an exception is thrown, the remaining code
in the try block is skipped, just as in the case
of the return statement in a function, and every
object created within the try block is destroyed - The throw object is caught by the catch block
where execution continues - The execution continues with the next statement
after the catch block
- while (ch y ch Y)
-
- cout ltlt Enter height
- cin gtgt height
- try
-
- if (height gt 300)
- throw height exceeds maximum
- if (height lt 0)
- throw height below minimum
- cout ltlt Inch equivalent ltlt
- ToInches(height)
-
- catch(const char msg)
-
- cout lt msg ltlt endl
-
- .....
13How it works
- When no exception is raised in the try block,
then catch block is skipped. - You can throw exceptions anywhere in the try
block - The operand following the throw keyword can be
any expression and the type of the result of the
expression determines the type of the exception
thrown (can be any type - basic type or user
defined class type) - The input type to the catch statement (the type
of the exception object) is defined as in
function declaration
- while (ch y ch Y)
-
- cout ltlt Enter height
- cin gtgt height
- try
-
- if (height gt 300)
- throw height exceeds maximum
- if (height lt 0)
- throw height below minimum
- cout ltlt Inch equivalent ltlt
- ToInches(height)
-
- catch(const char msg)
-
- cout lt msg ltlt endl
-
14Catching Exceptions
- You must supply at least one catch block for a
try block - try
-
- if (Height gt 100)
- throw height exceeds maximum
- if (Height lt 9)
- throw height below minimum
- // do what you want to do with the
height - cout ltlt do you want to continue?
- cin gtgt ch
-
- NOT ALLOWED!
15Catching Exceptions
- Catch blocks must immediately follow the try
block without any program code between them. - try
-
- if (Height gt 100)
- throw height exceeds maximum
- if (Height lt 9)
- throw height below minimum
- // do what you want to do with the
height - cout ltlt do you want to continue?
- cin gtgt ch
-
- cout ltlt ..... // not allowed
- catch(const char msg)
-
- cout lt msg ltlt endl
-
16Catching Exceptions
- Catch blocks will catch exceptions of the correct
type that occur in the code in the immediately
preceding try block, including the ones thrown by
functions called within the try block. - try
-
- if (Height gt 100)
- throw height exceeds maximum
- if (Height lt 9)
- throw height below minimum
- f1(height)
-
- catch(const char msg)
-
- cout lt msg ltlt endl
-
17Nested tries
- In case of nested try blocks
- if an exception is thrown from within an inner
try block which is not followed by a catch block
with the right type, the catch handlers for the
outer try block will be searched. - If a catch block cannot handle the particular
exception it has caught, it can rethrow the
exception.
18try while (ch y ch Y)
cout ltlt Enter Height cin gtgt
Height try if
(Height gt 300) throw height
exceeds maximum if (Height lt 1)
throw Height // do what you
want to do with the height cout ltlt
do you want to continue? cin gtgt
ch catch(const char
msg) cout lt msg ltlt endl
catch(ind BadHeight)
cout ltlt BadHeight ltlt is below minimumltlt
endl
- The exception of type const char is caught by
the catch block in the inner try block
- The exception of type int has no catch handler
for exceptions of that type, so the the catch
handler in the outer try block is executed
19Catching exceptions
- If you want to catch any exception that is thrown
in a try block, you specify this as - catch ()
-
- // code to handle any exception
-
- This catch block must appear last if you have
other catch blocks defined for the try block. - Note that in this catch block, you do not know
what type of exception has occured and cannot
reference an object
20Catching Exceptions
main() try throw "error"
catch (int i)
If an exception is not caught by any catch
statement because there is no catch statement
with a matching type, the special function
terminate will be called. This function is
generally defined so that it terminates the
current process immediately showing an "Abnormal
termination" error message.
21Exception Objects and Good Use of Exceptions
22(No Transcript)
23(No Transcript)
24(No Transcript)
25Exception Class Hierarchies
26Inheritance for Exception Classes
- We can use inheritance for abstraction!
- class MathErr //Base class for a hierarchy of
math exceptions - class Overflow public MathErr
- class Underflow public MathErr
- class ZeroDivide public MathErr
-
- Now we can catch any of these exceptions
- try // ...
- catch (Overflow) / ... /
- catch (Underflow) / ... /
- catch (MathErr) / ... /
- try can catch various exceptions, distinguishing
them by their class names--better than switch
27Exception Inheritance
Example try ... ... catch
(SpecialExceptionType1 e) ... catch
(SpecialExceptionType2 e) ... catch
(GeneralExceptionType e) ... catch(...)
...
SpecialExceptionType1 and SpecialExceptionType2
are inherited from GeneralExceptionType. SpecialE
xceptionType1 and SpecialExceptionType2 have
their own handling block (catch block). All
other exception inherited from GeneralExceptionTyp
e are handled in common catch block. All other
exceptions (that dont have GeneralExceptionType
as a base) are handled in the last catch block.
28Exception Classes
class CExceptionpublic___char
message___CException( char m ) message m
___Report() try ___Initialize()___Run()
___Shutdown() catch( CException e )
___e.Report()
29Extra Slides
- Explaining exception handling more compactly
30(No Transcript)
31(No Transcript)
32(No Transcript)
33(No Transcript)
34(No Transcript)
35Stack Unwinding
36Stack unwinding
If exception is thrown in a try block (in a
function that is called from a try block or in a
function that is called from a function that is
called from a try block and so on), all local
objects allocated from the stack after the try
block was entered are released and their
destructors are called. This process is called
stack unwinding. This process guaranties that
when we try to recover from an error, there are
no inconsistent data in the stack and try block
can be started again if desired.
37Stack unwinding
Example 1. void main() try A
a f1() void f1() B
b f2() void f2() C c
throw Exception e
If error occurs in the function f2, the
destructors for objects a, b and c are called and
those objects are deleted from the stack.
38Exception Classes in C
39- C exception handling allows a clean separation
between error detection and error handling. - A library developer may be able to detect when an
error occurs, such as an argument out of range,
but the developer doesn't know what to do about
it. - You, the user, can't always detect an exceptional
condition, but you know how your application
needs to handle it. - Hence, exceptions constitute a protocol for
runtime error communication between components of
an application.
40Standard exception classes
C standard defines the following class
hierarchy for exceptions. It is meant to serve
as a starting point so that programmers can
inherit and develop their own exceptions. The
base class for this class hierarchy is exception.
41C Exception Classes
Some functions of the standard C language
library send exceptions that can be captured if
we include them within a try block. These
exceptions are sent with a class derived from
stdexception as type. This class
(stdexception) is defined in the C standard
header file ltexceptiongt and serves as base for
the standard hierarchy of exceptions
include ltiostreamgt include ltexceptiongt using
namespace std main() try char c
new char10 catch (stdexception e)
cout ltlt "Exception " ltlt e.what()
42Standard exception classes
Exception class hierarchy exception
bad_alloc //class bad_alloc public
exception bad_cast bad_typeid logic_er
ror domain_error invalid_argument length_
error out_of_range runtime_error range_err
or overflow_error underflow_error ios_base
failure bad_exception
43Standard exception classes
Exception class hierarchy exception
bad_alloc bad_cast bad_typeid lo
gic_error domain_error invalid_argument l
ength_error out_of_range runtime_error ran
ge_error overflow_error underflow_error io
s_basefailure bad_exception
A logic error indicates an inconsistency in the
internal logic of a program, or a violation of
pre-conditions on the part of client software.
For example, the substr member function of the
standard string class throws an out_of_range
exception if you ask for a substring beginning
past the end of the string. A bad_alloc
exception occurs when heap memory is exhausted.
C will generate a bad_cast exception when a
dynamic_cast to a reference type fails. If you
rethrow an exception from within an unexpected
handler, it gets converted into a bad_exception.
If you attempt to apply the typeid operator to a
null expression, you get a bad_typeid exception.
44Memory allocation errors
- Some build-in operations (global or class
operations) throw an exception when they dont
succeed to complete the asked operation or they
can be asked to do so. - There are three options how memory allocation
errors can be handled - Option 1. Conventional way new returns 0 when
allocation fails - Option 2. Programmer can write his/her own
new_handler - Option 3. New throws an exception (bad_alloc) if
allocation fails.
45(No Transcript)
46Input /output errors
- It is possible to make input stream to throw an
exception when an error flag is set. - This is done with the member function
exceptions. - The parameter is used to indicate what bits
should cause the exception.
For example, the call cin.exceptions(iosfail
iosbad) makes the cin object to throw the
exception iosfailure, if failbit or bad bits
are set in the following input operations. The
exception type is ios_basefailure. If
exception has occurred, we can test the error
flags to find out what error caused the
exception.
47Example for cin.exceptions
- // Read in two floating point numbers and display
the sum. - include ltiostreamgt // stdcout,
stdcin - include ltostreamgt // ltlt, stdendl
- include ltistreamgt // gtgt
- int main()
-
- double a // Number value entered by
the user. - double b // Number value entered by
the user. - stdcin.exceptions( stdios_baseiostate(
-1 ) ) - //We want to use exception handling
- stdcout ltlt "Number A, please? "
- stdcin gtgt a
- stdcout ltlt "Number B, please? "
- stdcin gtgt b
48Out of range errors
If we use vector or strings we can random access
the individual elements in the vector or
characters in the string. If we use indexing
operator operator, the program crashes if index
is out of range. If we use a new member
function (at(i)) for indexing instead or override
the operator, we can throw an out_of_range
exception if index is out of range.
49Exceptions in Classes
class Vector //detects out of range errors as
exceptions int p int sz public
class Range //an exception class, defined
within class Vector int operator
(int i) if (0lti i lt sz)
return pi //within range, OK
throw Range() //exception--throw a Range
object
50Exceptions in Classes more useful/complete
version
class Vector //detects out of range errors as
exceptions public Vector(int n)
size(n) p new intsize class Range
//an exception class, defined within class
Vector int operator (int i) try
if (0lti i lt size)
return pi //within range, OK
else throw Range()
//exception--throw a Range object
catch (Range r) cout ltlt "Out of range
error" private int p int
size
51Stack Class
- include "stackExcp.h"
- void iStackpop( int top_value )
-
- if ( empty() )
- throw popOnEmpty()
- top_value _stack --_top
- cout ltlt "iStackpop() " ltlt top_value ltlt
endl -
- void iStackpush( int value )
-
- cout ltlt "iStackpush( " ltlt value ltlt " )\n"
- if ( full() )
- throw pushOnFull()
- _stack _top value
- // stackExcp.h
- include ltvectorgt
- class iStack
- public
- class popOnEmpty
- .
-
- class pushOnFull
- .
-
- iStack( int capacity )
- _stack( capacity ), _top( 0 )
- bool pop( int top_value )
- bool push( int value )
- bool full()
52Sample Codes
53Sample Codes
main() try throw "error"
catch (int i) cout ltlt "caught int
exception"ltlt endl catch (const char
c) cout ltlt "caught"ltlt endl
54Sample Codes
try throw 1 catch(...) cout ltlt
"Caught exception!" ltlt endl
55Beauty of exception handling in C
- Instead of terminating the program, you can write
more robust and fault-tolerant code - Instead of returning a value representing error
(e.g., 0 or NULL), we explicitly separate error
handling code form "ordinary" code - We can write more understandable code
56Unexpected Case Handling Methods Summary
- Programmers if statements
- Main approach to dealing with unexpected (also
very much expected) situations in basic/personal
programs. - E.g. File unopened, user entered wrong data,...
- Assert()
- Catches situations that SHOULD NOT happen
- E.g. Other programmers in the group told you how
their functions work. You assert this, just to
make sure (so they dont propagate and you wont be
able to find where the bugs are) - Try/Catch
- anything not covered by the above
- Or when there are too many possible problems
making the code long/ugly, gathers all the
handling code in one part - E.g. Disk drive etc. not working
57Good Resources
- http//www.freshsources.com/Except1/ALLISON.HTM