CS212: Object Oriented Analysis and Design Exception Handling
Introduction Exception handling allows you to manage run-time errors In an orderly fashion Program can automatically invoke an error-handling routine It automates much of the error-handling code
Error Conditions Division by 0, or values that are too large or small for a type No memory available for dynamic allocation Errors on file access, for example, file not found Attempt to access an invalid address in main memory Invalid user input
Traditional Error Handling Errors in function calls are indicated by special return values Global error variables or flags are set or unset when errors occur if( func()> 0 ) // Return value positive => o.k. else // Treat errors Error variables and flags must also be checked after every corresponding action. Need to continually check for errors while a program is executing
Exception Handling Concept A new approach to error handling Keeping the normal functionality of the program separate from error handling Errors occurring in one particular part of the program Errors are reported to another part of the program, known as the calling environment The calling environment performs central error handling.
Exception handling in C++ C++ exception handling is built upon three keywords: try, catch, and throw. Program statements to be monitored are contained in a try block If an exception occurs within the try block, it is thrown The exception is caught, using catch, and processed
Structure of try-catch block // try block } catch (type1 arg) { // catch block catch (type2 arg) { catch (type3 arg) { .. . catch (typeN arg) { Code to be monitored Possible to have more than one catch for a single try Demonstration1
Throwing exception throw generates the exception specified by exception throw must be executed from within a try block itself From any function called from within the try block Demonstration2 A try block can be localized to a function Demonstration3
Stack Unwinding The exception object is then thrown and the program control leaves the try block Any changes to the stack that took place after entering the try block are unwound The process of removing function entries from function call stack at run time is called Stack Unwinding Allows back out of the normal program flow in an orderly manner Demonstration
Searching for Handlers After the try block the PC searchers for the appropriate catch block Always performed sequentially beginning with the first catch block Exception declaration of the handler determines whether the handler should be executed Identical to the exception type thrown A base class of the exception type A base class pointer and the exception is a pointer to a derived class
Multiple catch Statements It is possible to have multiple condition to throw exception For individual throw statement, one catch statement is used Similar to switch statement Demonstration
Catch all/ Generic handler Similar to the tradition switch case, captures any type of exceptions (generic handler) A special syntax in the catch statement with an exception declaration consisting of just three dots. General exception handler to be defined last catch( ... ) { // General handler for // all other exceptions }
Exception Classes Exception classes are defined to categorize exceptions throw statement is used to throw an object belonging to a specific exception class. An exception class need not contain data members or methods type, which is used by the calling environment to identify the error, is important Contains members that provide more specific information on the cause of the error
Continuing the Program After executing a handler, the program continues with the first statement following the catch blocks Unless the handler throws another exception Terminates the program After completing exception handling, the exception object that was thrown is destroyed
Catching Class Types An exception can be of class types that you create Most exceptions will be class types rather than built-in types To create an object that describes the error that occurred Information can be used by the exception handler to help it process the error Demonstration5
Nesting exception handling A try block can contain additional try blocks This allows using the handlers in a nested try block for special purpose error handling Leaving the handlers in the surrounding try block to deal with remaining errors You can also nest a try block within a catch block.
try { // Type1 exceptions are thrown here. // Type1 and Type2 exceptions are thrown here. } catch( Type2 e2) // Type2 exceptions are pre-handled here throw; // and thrown again. // Other Type1 exceptions can be thrown. catch( Type1 e1) // Type1 exceptions are handled here. catch(...) // All remaining exceptions are handled here, // particularly Type2 exceptions.
Control transfer in nested case Try blocks are nested and a throw occurs in a function called by an inner try block try { func1(); try { func2(); } catch (spec_err) { /* ... */ func3(); catch (type_err) { /* ... */ } // if no throw is issued, control resumes here.
Standard exceptions C++ Standard library provides a base class Designed to declare objects to be thrown as exceptions Defined in the <exception> header This class has a virtual member function called “what” Override in derived classes to contain some sort of description of the exception Demonstration
Types of exceptions 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 All exceptions thrown by components of the C++ Standard library throw exceptions derived from this exception class.
Exception they are insufficient, inelegant, and error prone. Exception handling Terminate the program (an exception isn’t caught) Return a value representing ‘‘error’’ (isn’t always feasible) Return a legal value and leave the program in an illegal state, (calling function may not notice the error) Call a function supplied to be called in case of ‘‘error.’’ Exception they are insufficient, inelegant, and error prone.
Types of try block A try block to indicate which areas in your program that might throw exceptions you want to handle immediately A function try block to indicate that you want to detect exceptions in the entire body of a function try { // statements } handlers { // statemnts } <Return type> functionName try <member initializer list> { // function body } handlers { // statemnts } Demonstration
Exception Specifications We can restrict the type of exceptions that a function can throw outside of itself Prevent a function from throwing any exceptions whatsoever Add a throw clause to a function definition Data types contained in the comma-separated type-list may be thrown ret-type func-name(arg-list) throw(type-list) { // ... }
Restricting Exceptions Throwing any other type of expression will cause abnormal program termination Standard library function unexpected() By default, this causes abort() to be called Specify your own unexpected handler if you like Demonstration
Rethrowing an Exception A handler can’t completely handle the error. Rethrow an expression from within an exception handler Calling throw, by itself, with no exception This causes the current exception to be passed on to an outer try/catch sequence. Allow multiple handlers access to the exception
Re-Throw throw ; // rethrow the exception void h () { try { // code that might throw Math errors } catch (Matherr) { if (can_handle_it_completely) { // handle the Matherr return ; else { // do what can be done here throw ; // rethrow the exception Demonstration
Handling Derived-Class Exceptions Need to be careful in ordering the catch statements Trying to catch exception types involving base and derived classes Want to catch exceptions of both a base class type and a derived class type Demonstration
terminate() During stack unwinding a destructor throws an exception That exception is not handled. The expression that is thrown also throws an exception The constructor or destructor of a nonlocal static object throws an exception The exception is not handled. A function registered with atexit() throws an exception
unexpected() A function with an exception specification throws an exception The exception is not listed in its exception specification The unexpected() function is called The unexpected() function calls the function pointed to by unexpected_handler By default, unexpected_handler points to the function terminate()
Setting the Terminate and Unexpected Handlers These functions call other functions to actually handle an error terminate() abort(); unexpected() terminate() Allows the program to take full control of the exception handling subsystem set_terminate(): terminate handler set_unexpected(): unexpected handler Demonstration
uncaught_exception( ) Detects if the current thread has a live exception object An exception has been thrown or rethrown and not yet entered a matching catch clause uncaught_exception detects if stack unwinding is currently in progress Detects how many exceptions have been thrown or rethrown And not yet entered their matching catch clauses
Standard Exception Classes (SEC) Exception classes derived from logic_error Exception classes derived from runtime_error invalid_argument Invalid argument out_of_range Argument value not in its expected range length_error Length exceeds maximum capacity domain_error Domain error reported by the implementation range_error Range error in internal computation underflow_error Arithmetic underflow error overflow_error Arithmetic overflow error
Exception and constructors How to report errors from a constructor Constructor does not return a separate value for a caller to test Return an object in a bad state Set a nonlocal variable (e.g., errno) to indicate that the creation failed Don’t do any initialization in the constructor Mark the object ‘‘uninitialized’’
Different scenarios Exceptions and New What happens if X ´s constructor throws an exception? Resource Exhaustion Resumption, Termination Exceptions and Member Initialization A member initializer (directly or indirectly) throws an exception Exceptions in Destructors Normal call Call during exception handling