exception.h
The exception.h
interface makes it possible for
clients to specify a handler for an exceptional conditions in a
syntactically readable way. As a client, your first step
is to declare an exception condition name by declaring
a variable of type exception, as in
exception MyException;
Normal visibility rules apply, so that you should declare the
exception variable at the appropriate level. For example, if an
exception is local to an implementation, it should be declared
statically within that module. If an exception condition is
shared by many modules, the exception variable should be declared
in an interface and exported to all clients that need it. This
package defines and exports the exception ErrorException
,
which is likely to be sufficient for many clients.
The basic functionality of exceptions is that one piece of code
can "throw" an exception so that it can then be "caught" by
special code in a dynamically enclosing section of the program.
Exceptions are triggered by calling the pseudo-function
throw
with the exception name, as in
throw(MyException);
Exceptions are handled using the try
statement
(actually implemented using macros), which has the form:
try { . . . statements in the body of the block . . . } catch (exception1) { . . . statements to handle exception 1 . . . } catch (exception2) { . . . statements to handle exception 2 . . . } catch (ANY) { . . . statements to handle any exception . . . } finally { . . . statements to be executed before exit in all cases . . . } endtry
Any number of catch
clauses may appear. The
ANY
and finally
clauses are optional.
When the program encounters the try
statement, the
statements in the body are executed. If no exception conditions
are thrown during that execution, either in this block or by a
function call nested inside this block, control passes to the end
of the try
statement when the last statement in the
block is executed. If an exception is thrown during the dynamic
execution of the block, control immediately passes to the statements
in the appropriate catch
clause. Only the statements
in that clause are executed; no break
statement is
required to exit the block.
The try
statement guarantees that the statements in
the finally
clause, if present, will always be executed,
even if an exception is thrown that is caught at a higher level.
If no handler for the exception appears anywhere in the control history, the program exits with an error.
Examples of use:
1. Catching errors
The following code fragment traps calls to error
, so
that the program does not quit but instead returns to the top-level
read-and-execute loop.
while (true) { try { printf("> "); cmd = readCommand(); executeCommand(cmd); } catch (ErrorException) { printf("error: %s\n", (string) getExceptionValue()); -- additional handling code, if any -- } endtry }
If either readCommand
or executeCommand
calls error
, control will be passed back to the main
loop, after executing any additional handler code. The error
message is passed as the exception value and can be printed as
shown in the example.
2. Handling control-C (Unix systems)
The following code extends the example above so that typing
^C
also returns to top-level:
#includestatic exception ControlCException; static int errorCount = 0; static int controlCHandler(); main() { string cmd; signal(SIGINT, controlCHandler); while (true) { try { printf("> "); cmd = readCommand(); executeCommand(cmd); } catch (ControlCException) { printf("^C\n"); signal(SIGINT, controlCHandler); } catch (ErrorException) { errorCount++; } endtry } } static int controlCHandler() { throw(ControlCException); }
Types | |
This type is used to define the general class of exceptions. | |
Predefined exception type for the error function. | |
Constant | |
Predefined exception type that allows handlers to catch an arbitrary exception. |
typedef struct { string name; } exception;
extern exception ErrorException;
error
function.