exception.h

This interface exports a portable exception-handling mechanism for C.

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:

   #include 
 
   static 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
exception This type is used to define the general class of exceptions.
ErrorException Predefined exception type for the error function.
Constant
ANY Predefined exception type that allows handlers to catch an arbitrary exception.

Type detail


typedef struct { string name; } exception;
This type is used to define the general class of exceptions. Exceptions are specified by their address, so that the actual structure does not matter. Strings are used here so that exporters of exceptions can store the exception name for the use of debuggers and other tools.

extern exception ErrorException;
Predefined exception type for the error function.