Exception handling is a mechanism that allows two separately developed program components to communicate when a program anomaly, called an exception, is encountered during the execution of the program. In this chapter we first look at how to raise, or throw, an exception at the location where the program anomaly is encountered. We then look at how to associate handlers, or catch clauses, with a set of program statements using a try block, and we look at how exceptions are handled by catch clauses. We then introduce exception specifications, a mechanism that associates a list of exceptions with a function declaration and that guarantees that the function does not throw any other types of exceptions. We end the chapter with a discussion of design considerations for programs that use exceptions. Exceptions are run-time anomalies that a program may detect, such as division by 0, access to an array outside of its bounds, or the exhaustion of the free store memory. Such exceptions exist outside the normal functioning of the program and require immediate handling by the program. The C++ language provides built-in language features to raise and handle exceptions. These language features activate a run-time mechanism used to communicate exceptions between two unrelated (often separately developed) portions of a C++ program. When an exception is encountered in a C++ program, the portion of the program that detects the exception can communicate that the exception has occurred by raising, or throwing, an exception.
Exception handling provides a standard mechanism for coding responses to runtime errors or exceptions. Exception handling is on by default. To turn it off, you must use the +noeh option. If your executable throws no exceptions, object files compiled with and without the +noeh option can be mixed freely. However, in an executable which throws exceptions (HP aC++ runtime libraries throw exceptions), you must be certain that no exception is thrown in your application which will unwind through a function compiled without the exception handling option turned on. In order to prevent this, the call graph for the program must never have calls from functions compiled without exception handling to functions compiled with exception handling (either direct calls or calls made through a callback mechanism). If such calls do exist, and an exception is thrown, the unwinding can cause:
•
Non-destruction of local objects (including compiler generated temporaries).
•
Memory leaks when destructors are not executed.
•
Runtime errors when no catch clause is found.