except.h File Reference

Documentation for Exception Handling Library (CBL). More...

#include <setjmp.h>

Include dependency graph for except.h:

This graph shows which files directly or indirectly include this file:


Data Structures

struct  except_t
struct  except_frame_t

Defines

#define EXCEPT_RAISE(e)   except_raise(&(e), __FILE__, __LINE__)
 raises exception e.
#define EXCEPT_RERAISE   except_raise(except_frame.exception, except_frame.file, except_frame.line)
 raises the exception again that has been raised most recently.
#define EXCEPT_RETURN   switch(except_stack=except_stack->prev, 0) default: return
 returns to the caller function within a TRY-EXCEPT statement.
#define EXCEPT_TRY
 starts a TRY statement.
#define EXCEPT_EXCEPT(e)
 starts an EXCEPT(e) clause.
#define EXCEPT_ELSE
 starts an ELSE clause.
#define EXCEPT_FINALLY
 starts a FINALLY clause.
#define EXCEPT_END
 ends a TRY-EXCEPT or TRY-FINALLY statement.

Enumerations

enum  { EXCEPT_ENTERED = 0, EXCEPT_RAISED, EXCEPT_HANDLED, EXCEPT_FINALIZED }

Functions

exception raising functions:
void except_raise (const except_t *, const char *, int)
 raises an exception and set its information properly.

Variables

except_frame_t * except_stack
 stack for handling nested exceptions.

Detailed Description

Documentation for Exception Handling Library (CBL).

Header for Exception Handling Library (CBL).


Define Documentation

#define EXCEPT_ELSE

Value:

if (except_flag == EXCEPT_ENTERED)        \
                        except_stack = except_stack->prev;    \
                } else {                                      \
                    except_flag = EXCEPT_HANDLED;
starts an ELSE clause.

If there is no matched EXCEPT clause for a raised exception the control moves to the statements following the ELSE clause.

#define EXCEPT_END

Value:

if (except_flag == EXCEPT_ENTERED)        \
                        except_stack = except_stack->prev;    \
                }                                             \
                if (except_flag == EXCEPT_RAISED)             \
                    EXCEPT_RERAISE;                           \
            }
ends a TRY-EXCEPT or TRY-FINALLY statement.

If a raised exception is not handled by the current handler, it will be handled by the previous handler if any.

#define EXCEPT_EXCEPT (  ) 

Value:

if (except_flag == EXCEPT_ENTERED)          \
                        except_stack = except_stack->prev;      \
                } else if (except_frame.exception == &(e)) {    \
                    except_flag = EXCEPT_HANDLED;
starts an EXCEPT(e) clause.

When an exception e is raised, its following statements are executed. Finishing them moves the control to the end of the TRY statement.

#define EXCEPT_FINALLY

Value:

if (except_flag == EXCEPT_ENTERED)        \
                        except_stack = except_stack->prev;    \
                }                                             \
                {                                             \
                    if (except_flag == EXCEPT_ENTERED)        \
                        except_flag = EXCEPT_FINALIZED;
starts a FINALLY clause.

It is used to construct a TRY-FINALLY statement, which is useful when some clean-up is necessary before exiting the TRY-FINALLY statement; the statements under the FINALLY clause are executed whether or not an exception occurs. EXCEPT_RERAISE macro can be used to hand over the not-yet-handled exception to the previous handler.

Warning:
Remember that, since raising an exception pops up the execption stack, re-raising an exception in a FINALLY clause has the effect to move the control to the outer (previous) handler. Also note that, even if not explicitly specified, a TRY-EXCEPT- FINALLY statement (there are both EXCEPT and FINALLY clauses) is possible and works as expected.

#define EXCEPT_RETURN   switch(except_stack=except_stack->prev, 0) default: return

returns to the caller function within a TRY-EXCEPT statement.

In order to maintain the stack handling nested exceptions, the ordinary return statement should be avoided in statements (referred to as S below; see the explanation for EXCEPT_TRY) following EXCEPT_TRY. Because return has no idea about the exception frame, retruning without using EXCEPT_RETURN from S spoils the exception stack. EXCEPT_RETURN adjusts the stack properly by popping the current exception frame before returning to the caller.

Warning:
Note that the current exception frame is popped when an exception occurs during execution of S and before the control moves to one of EXCEPT, ELSE and FINALLY clauses, which means using EXCEPT_RETURN there is not allowed since it affects the previous, not the current, exception frame.

#define EXCEPT_TRY

Value:

{                                                  \
                volatile int except_flag;                      \
                /* volatile */ except_frame_t except_frame;    \
                except_frame.prev = except_stack;              \
                except_stack = &except_frame;                  \
                except_flag = setjmp(except_frame.env);        \
                if (except_flag == EXCEPT_ENTERED) {
starts a TRY statement.

Statements (referred to as S hereafter) whose exception is to be handled in EXCEPT, ELSE or FINALLY clause follow.

Warning:
Do not forget using EXCEPT_RETURN when returning from S. See EXCEPT_RETURN for more details. Besides, The TRY-EXCEPT/FINALLY statement uses the non-local jump mechanism provided by <setjmp.h>, which means any restriction applied to <setjmp.h> also applies to the TRY-EXCEPT/FINALLY statement. For example, the standard does not guarantee that an automatic non-volatile variable belonging to the function which contains setjmp() preserves its last stored value when it is updated between a call to setjmp() and a call to longjmp() with the same jmp_buf.


Enumeration Type Documentation

anonymous enum

Enumerator:
EXCEPT_ENTERED  exception handling started and no exception raised yet
EXCEPT_RAISED  exception raised and not handled yet
EXCEPT_HANDLED  exception handled
EXCEPT_FINALIZED  exception finalized


Function Documentation

void except_raise ( const except_t *  e,
const char *  file,
int  line 
)

raises an exception and set its information properly.

EXCEPT_RAISE and EXCEPT_RERAISE macros call except_raise() with __FILE__ and __LINE__ predefined macros (and __func__ if C99 supported) for the file and line parameters. So in general there is little chance to call except_raise() directly in application code.

Possible exceptions: assert_exceptfail

Unchecked errors: foreign data structure given for e

Parameters:
[in] e exception to raise
[in] file file name where exception occurred
[in] func function name where exception occurred (if C99 supported)
[in] line line number where exception occurred
Returns:
except_raise() cannot return anything
Todo:
Improvements are possible and planned:
  • it would be useful to show stack traces when an uncaught exception leads to abortion of a program. The stack traces should include as much information as possible, for example, names of caller functions, calling sites (file name, function name and line number) and arguments.


Generated on Mon Jan 24 01:12:36 2011 for The Exception Handling Library by  doxygen 1.5.8