200 likes | 220 Views
CSCI-383. Object-Oriented Programming & Design Lecture 22. Exception Handling. An exception is a run-time program exceptional event Exceptions include such things as Divide by zero Out of memory Arithmetic overflow
E N D
CSCI-383 Object-Oriented Programming & Design Lecture 22
Exception Handling • An exception is a run-time program exceptional event • Exceptions include such things as • Divide by zero • Out of memory • Arithmetic overflow • Generally, there are several ways that one can handle an exception when it occurs, including • Ignore the error • Handle the error and terminate the program • Handle the error and continue execution
How Could a Library Author Deal with an Error? • Terminate the program • Do you really want your library to kill you? • Print an error message and continue • Would you allow a library to clobber your screen?
Exception Handling • Exception handling is similar in concept to interrupt handling • When an exception is raised, control branches to a separate function, called an exception handler, where the exception is processed • Exception handlers may have a different scope than the function in which the exception occurs • Thus, the language also must provide some mechanism for passing information from the routine where the exception occurs to the exception handler
Exception Handling • In an ANSI C program, exception handling may look something like this char* p = (char*)malloc(sizeof(char)*size); if (p==NULL) printf(“Unable to allocate character array.\n”); exit(1); } • This is analogous to the “good ol’ days” of programming when data and functions coexisted on a casual basis • Such code is usually intermingled with the conventional processing code of the program. This can make the processing code difficult to read, understand, and maintain
Exception Handling • C++ provides constructs to support exception handling more directly • Exceptions can be raised by programmer’s code, by the system, or by library code • Although using exception handling can simplify a C++ program, it also can make the program even more complex than it was originally
Exception Handling • C++ provides three new constructs for exception handling. They are • try blocks • throw statements • catch blocks • A try block is a block of statements in which exceptions are to be detected • A throw statement throws or raises an exception • A catch block is an exception handler • Handout #10contains a simple program that illustrates the use of exception handling in C++
Exception Handling: throw • The throw statement usually appears with one argument, which is an exception object to be thrown • The exception object can be of a builtin or user-defined type • Sometimes, the exception object is empty. This might occur if the type of the object is all the information the exception handler needs to do its work • For example, one might create an exception object class such as: class DivideByZero{};
Exception Handling: throw • The C++ standard library contains some predefined exception object classes for commonly thrown exceptions • If an object is thrown, it makes sense that it must be caught by something. It generally is caught by a catch block
Exception Handling: try • A try block is the keyword try statement followed by a block of statements in which exceptions are detected • A try block always is followed by a sequence of one or more catch blocks • When an exception is raised while executing the code contained in a try block, the exception object is thrown to the closest exception handler that specifies the appropriate type of exception object • If none of the catch blocks specifies an appropriate type of exception object, the object is thrown out to the next level of try block within which execution is taking place
Exception Handling: try • If the exception makes it all the way to the global level without being handled, it triggers a call to a builtin function named terminate, which aborts the program execution • Note that the throw statements in handout #10 are in methods that are not implemented within a try block. Does this mean that terminate will be called when the exceptions are thrown? Not necessarily!
Exception Handling: try • Though the point of execution currently may be outside the scope of the try block, C++ begins to do a stack unwind when the exception is thrown • If the stack is entirely unwound and no appropriate exception handler is found, then terminate is called
Exception Handling: catch • Each catch block begins with the keyword catch, followed by a single parenthesized parameter (in most cases) and a block of statements • When an exception is raised within the try block, the catch blocks are examined – in the order in which they appear – in an attempt to find an appropriate exception handler
Exception Handling: catch • The criteria used to select an appropriate exception handler are based on comparing the type of the exception object to the type of the parameter • If the class of the catch parameter matches exactly the class of the exception object, the catch block is selected as appropriate • If the class of the catch parameter is a public base class of the exception class object, the catch block is selected as appropriate • If the catch parameter is of a pointer (or reference) type to which the pointer (or reference) type of the exception object can be converted, the catch block is selected as appropriate • If the catch parameter is (...), the catch block is selected as appropriate. This is the “catch all”
Exception Handling: catch • One must exercise care when ordering the catch blocks following a try block • Here is an incorrect example: it assumes that ArrayErr is the public base class of RangeErr catch(...) {...} catch(ArrayErr&) {...} catch(RangeErr&) {...} • What would be a correct ordering?
Exception Handling: catch • The parenthesized parameter can consist of just a type followed by an identifier name, or simply a type. It can also consist only of ellipsis • When an exception handler is chosen and has finished executing, execution continues with the statement following the last handler in the sequence of handlers associated with that try block
Exception Handling: catch • A handler can re-throw an exception (and the exception object) if it decides that it cannot handle the exception or if it has finished processing the exception and wants to pass it along for further processing • This is done by including the statement throw; in the handler
Standard Library Exception Hierarchy • Experience has shown that exceptions fall nicely into a number of categories • The C++ standard library includes a hierarchy of exception classes exception runtime_error logic_error overflow_error underflow_error invalid_argument length_error out_of_range bad_alloc bac_cast bad_type_id bad_exception
Standard Library Exception Hierarchy • This hierarchy is headed by base class exception, which contains virtual function what, which derived classes can override to issue appropriate error messages • Handout #11 • Notice that the catch block in handout #11 could also have been catch(runtime_error& runtimeException)
Throw List • One can restrict the types of exceptions that can be thrown in a function by specifying a throw list as part of the function prototype. For example void myFunction(void) throw(RangeErr,DivideByZero) {...} • If one throws a different type of exception than those in the list, the system function unexpected is called, which (by default) calls terminate • An empty throw list (i.e., throw()) specifies that any exceptions thrown by the function will trigger a call to unexpected • Handout #12