Exception Handling in C++

C++ exception handling is geared to situations in which the function that detects the error can't or shouldn't handle it (e.g., divide by zero). Such a function will throw an exception There is no guarantee that there will an exception handler geared toward processing any particular kind of exception. If not, the program terminates.

An example

When a function detects an error it "throws" an exception. The operand of throw can be of any type. If the operand is an object, we call it an exception object.

This class' purpose is to be thrown when an exception is detected. It can be as complex or as simple as necessary depending on the information it wishes to pass to the user.

class DivByZeroEx { public: DivByZeroEx ( ) : m_message ("attempted divide by 0") { /* no code */ } const string& what ( )const { return m_message;} private: const string m_message; }; When the function quotient( ) detects that divide-by-zero is about to occur, it throws an exception rather than allowing your program to crash. double quotient(int num, int den) { if (den == 0) throw DivByZeroEx(); return static_cast<double>(num) / den; }

"try" and "catch"

try/catch Example

int main() { int numerator, denominator; double result; cout << "Input numerator and denominator" << endl; cin >> numerator >> denominator; try { result = quotient(numerator, denominator); cout << "The quotient is: " << result << endl; } catch (DivByZeroEx& ex) { // exception handler cerr << "Exception occurred: " << ex.what() << endl; } // code continues here return 0; }

What happens when quotient() throws an exception?

  1. A temporary copy of the throw operand is created and initialized.
  2. Control immediately exits the try block (all automatic objects defined within the try block are destroyed).
  3. Control proceeds to the appropriate catch block (if any).
  4. The copy of the operand initializes the catch block parameter, if there is one.
  5. After the code in the catch block completes, control passes to the first line of code after the last catch block for this try block.

Catch Blocks

A try block may have more than one associated catch block. try { // code that might throw an exception } catch (ExceptionObject1& ex1) { // exception handler code } . . . catch (ExceptionObject2& ex2) { // exception handler code } catch (ExceptionObjectN& exN) { // exception handler code } catch (...) { // default exception handler code }

Exceptions and Nested Function Calls

It is certainly not unusual for one function to call another. What happens when a nested function throws an exception? // function3 throws an exception void function3( ) { cout << "function3" << endl; throw int(42); } // function2 calls function3, but with no try/catch void function2( ) { function3( ); cout << "function2" << endl; } // function1 calls function2, but with no try/catch void function1( ) { function 2( ); cout << "function1" << endl; } // main calls function1, with try/catch int main( ) { try { function1( ); } catch (int) { cout << "Exception occurred" << endl; } return 0; } When an exception is thrown but not caught in the current scope, the function call stack is unwound and an attempt is made to catch the the exception in the next outer try/catch block.

Unwinding means that all local variables in that function are destroyed and control returns to the point the function was called.

Rethrowing an Exception

When an exception handler catches an exception and decides it cannot/should not process it, it can rethrow the exception.

A rethrown exception is detected by the next enclosing try block and handled by an associated catch block.

Exceptions can be rethrown back through multiple levels of nesting.

More syntax: try { // code that could throw an exception } catch { throw; // rethrow the exception to the next } // enclosing try block

Rethrow example

Application program // handles exception if full Add item to inventory // rethrows exception if full Insert item in list // rethrows exception if full Is list full? // throws exception if full

Last Modified: Monday, 28-Aug-2006 10:16:05 EDT