Lecture Notes for Advanced Programming II

7 February 2002 - Exceptions


  1. the error problem

    1. what happens if there's an error in a constructor

    2. what happens if there's an error in an overloaded operator

    3. the error pass-along problem

  2. out-of-band errors - exceptions

    1. not propagated along parameters, return values, or globals - constructors and operators

    2. can be ignored by intermediate code - pass-along

  3. exception basics

    1. the call stack

    2. the top of the call stack can throw an exception

    3. a procedure in the call stack can catch an exception

    4. the procedure closest to the top wanting the exception gets it

    5. the intervening processes are unwound - the catching process is the new call-stack top

    6. the throwing and intervening processes are terminated immediately

  4. exception problems

    1. intervening processes have no chance to clean up

    2. coordinated exceptions among independent modules requires work

  5. basic exception mechanisms - throw, catch, and try

    1. throw expr throws the value expr as an exception

      1. like return in syntax and semantics

      2. expr can be a value of any type

    2. catch ( type-spec [ name ] ) { body } - catches a thrown exception

      1. with no name, the actual exception is unknown

      2. exception types must match exactly - with no conversions but with polymorphism

      3. the ellipsis catch(. . .) { } catches any exception

      4. when caught, the body is executed with name (if defined) as a local variable.

    3. try { body } catch-stmt . . .

      1. execute the code in body - fall off the end with no exception

      2. jump from body to the catch-stmts on exception - a normal scope exit; destructors are called

      3. search for a matching catch-stmt in order

        1. an exception is considered handled as soon as a match is found

      4. after executing the associated catch body, continue after the try

      5. if no catch-stmt matches, terminate the current procedure and continue up the stack

  6. exception problems

    1. the scope of the try is not the scope of a catch

  7. exception refinements - it gets confusing

    1. an exception not handled by main() causes termination

    2. an exception thrown in a catch body is like any other exception

    3. exceptions raised in destructors cause immediate termination - no stack unwinding

  8. exception mechanism refinements

    1. exception class values

      1. <exception> defines the virtual class exception

        1. defines char * exception::what(void) const

      2. <stdexcept> defines some derived exceptions - runtime_error and logic_error

    2. a catch handler can rethrow an exception using throw

    3. a procedure can list the exceptions it throws with a throw clause

      1. throw ( ex1, ex2, . . . )

      2. follows the procedure's formal parameter list

      3. only the listed exceptions can be thrown from the procedure - other exceptions cause termination

      4. by default a procedure can throw all exceptions

  9. exception problems

    1. throw clauses are useful but dangerous - must list all possible exceptions; unlisted exceptions get turned into unexpected exceptions

  10. further exception refinements

    1. c++ throws several exceptions - bad_alloc in new in particular

      1. there's also a non-throwing new - this used to be standard

    2. auto_pointers provide a means for automatic resource recovery on exceptions

  11. some exception pointers

    1. don't use them - nasty, asynchronous, implicit control flow

    2. if you do use them

      1. make sure they indicate exceptional conditions - don't use them to exit a loop or return from a procedure; lisp programmers beware

      2. keep it as simple as possible - short throw-catch relations and simple values returned


This page last modified on 21 February 2002.