Exception handling

nxs_exception.h More...

Data Structures

struct  nxs_exception
 Structure representing an exception. More...
union  nxs_exception_data
 Const-safe holder of custom data. More...
struct  nxs_exception_type
 Structure representing a class of exceptions. More...

Defines

#define nxs_always
 Begins a block of code that should be executed whether or not an exception is thrown.
#define nxs_catch(_type, _var)
 Begins a block of code that will only be executed if an exception of class _type is thrown.
#define nxs_catch_any(_var)
 Begins a block of code that will be executed if any exception is thrown.
#define nxs_catch_only(_type, _var)
 Begins the only block of code that will only be executed if an exception of class _type is thrown.
#define nxs_end
 Performs necessary cleanup to avoid memory leaks from exception handling code.
#define nxs_exception_assert(_cond)
 Asserts that the value of _cond does not compare equal to zero.
#define nxs_exception_declare(_type)
 Declares (but does not define) an exception class by the name of _type.
#define nxs_exception_define(_parent, _type)
 Defines an exception class _type inheriting from _parent.
#define nxs_exception_define_root(_type)
 Defines an exception class _type that does not inherit from any other class.
#define nxs_raise(_type, _data)
 Raises a new exception of class _type.
#define nxs_rethrow(_exception)
 Rethrows the nxs_exception pointed to by _exception.
#define nxs_throw(_exception)
 Throws the nxs_exception pointed to by _exception.
#define nxs_try
 Begins a block of code that may throw exceptions.

Functions

void nxs_exception_cleanup (void)
 Releases any resources associated with the exception module.
bool nxs_exception_init (void)
 Initializes the exception module, returning true on success.
bool nxs_exception_is (const struct nxs_exception *exception, const struct nxs_exception_type *type)
 Determines whether exception is of the exception class type, or a subclass thereof.
static void nxs_exception_print_trace (const struct nxs_exception *exception)
 Unravels the backtrace of exception, listing all the functions it has passed through.

Variables

struct nxs_exception_type *const NXSAssertionFailureException
 Thrown when a condition given to nxs_exception_assert() fails.
struct nxs_exception_type *const NXSMemoryAllocationException
 Thrown when memory cannot be allocated for internal exception handling data.
struct nxs_exception_type *const NXSRootException
 A basic root exception type.

Detailed Description

nxs_exception.h

Note:
If NXS_EXCEPTION_THREAD_UNSAFE is defined when compiling this module (i.e. not simply including the header), no attempt will be made to enable thread-safe exceptions. Thread safety is implemented using the Multi-platform threads module (which means that said module must also be compiled into the library or your project), and is only available when NXS_THREAD_HAS_TLS is defined. If NXS_THREAD_HAS_TLS is not defined, including this header will define NXS_EXCEPTION_THREAD_UNSAFE itself.

This module must be initialized once with nxs_exception_init(), and nxs_exception_cleanup() should be called before the program exits.

Created by Justin Spahr-Summers on 2007-11-25. Copyright 2007. All rights reserved.

Define Documentation

#define nxs_always

Begins a block of code that should be executed whether or not an exception is thrown.

Unlike with other exception-handling systems, this block needs to be between the nxs_try and nxs_catch blocks. Functionality is similar to a more traditional finally block except for the positioning.

 nxs_try {
      ...
 } nxs_always {
      // perform cleanup actions to prevent resource leaks
      ...
 } nxs_catch_any (...) {
      ...
 }

Note:
It is legal to break out of a nxs_always block. Exception handling will continue as if execution had left the block normally.

A nxs_always block is in a different scope from a nxs_try block. This means variables declared in a nxs_try block cannot be accessed here. Variables declared in a higher scope and merely assigned to will work as intended.

Warning:
Variables of automatic storage duration local to the containing function that are not qualified with volatile and have been changed inside the nxs_try block are indeterminate if an exception is thrown. This is a restriction imposed by the mechanics of setjmp() and longjmp().

#define nxs_catch ( _type,
_var   ) 

Begins a block of code that will only be executed if an exception of class _type is thrown.

_var should be a variable to which to assign the nxs_exception pointer.

 nxs_try {
      ...
 } nxs_catch (NXSAssertionFailureException, nxs_exception *ex) {
      // perform some action based on the information given in 'ex'
      ...
 } nxs_catch_any (...) {
      ...
 }

See also:
nxs_exception_type

nxs_catch_any nxs_catch_only nxs_end

Note:
It is legal to break out of a nxs_catch block. Exception handling will continue as if execution had left the block normally.

A nxs_catch block is in a different scope from nxs_try, nxs_always, and other nxs_catch blocks. This means variables declared in any of the aforementioned blocks cannot be accessed here. Variables declared in a higher scope and merely assigned to will work as intended.

Warning:
It is illegal to return from a nxs_catch block or to exit its scope through the use of goto.

Variables of automatic storage duration local to the containing function that are not qualified with volatile and have been changed inside the nxs_try block are indeterminate. This is a restriction imposed by the mechanics of setjmp() and longjmp().

#define nxs_catch_any ( _var   ) 

Begins a block of code that will be executed if any exception is thrown.

One of this, nxs_catch_only(), or nxs_end must be present in any given exception handler. _var should be a variable to which to assign the nxs_exception pointer.

 nxs_try {
      ...
 } nxs_catch (NXSAssertionFailureException, nxs_exception *ex) {
      ...
 } nxs_catch_any (nxs_exception *ex) {
      // 'ex' cannot be an NXSAssertionFailureException at this point
      // now perform some action based on the information given in 'ex'
      ...
 }

Note:
It is legal to break out of a nxs_catch_any block. Exception handling will continue as if execution had left the block normally.

A nxs_catch_any block is in a different scope from nxs_try, nxs_always, and nxs_catch blocks. This means variables declared in any of the aforementioned blocks cannot be accessed here. Variables declared in a higher scope and merely assigned to will work as intended.

Warning:
It is illegal to return from a nxs_catch_any block or to exit its scope through the use of goto.

Variables of automatic storage duration local to the containing function that are not qualified with volatile and have been changed inside the nxs_try block are indeterminate. This is a restriction imposed by the mechanics of setjmp() and longjmp().

#define nxs_catch_only ( _type,
_var   ) 

Begins the only block of code that will only be executed if an exception of class _type is thrown.

This cannot be used with other nxs_catch() blocks. One of this, nxs_catch_any(), or nxs_end must be present in any given exception handler. _var should be a variable to which to assign the nxs_exception pointer.

 nxs_try {
      ...
 } nxs_catch_only (NXSAssertionFailureException, nxs_exception *ex) {
      // perform some action based on the information given in 'ex'
      ...
 }

Note:
It is legal to break out of a nxs_catch_any block. Exception handling will continue as if execution had left the block normally.

A nxs_catch_only block is in a different scope from nxs_try and nxs_always blocks. This means variables declared in either of the aforementioned blocks cannot be accessed here. Variables declared in a higher scope and merely assigned to will work as intended.

Warning:
It is illegal to return from a nxs_catch_only block or to exit its scope through the use of goto.

Variables of automatic storage duration local to the containing function that are not qualified with volatile and have been changed inside the nxs_try block are indeterminate. This is a restriction imposed by the mechanics of setjmp() and longjmp().

#define nxs_end

Performs necessary cleanup to avoid memory leaks from exception handling code.

One of this, nxs_catch_any(), or nxs_catch_only() must be present in any given exception handler.

#define nxs_exception_assert ( _cond   ) 

Asserts that the value of _cond does not compare equal to zero.

If _cond is zero, an NXSAssertionFailureException is thrown. If NDEBUG is defined, this does nothing and _cond is not evaluted.

#define nxs_exception_declare ( _type   ) 

Declares (but does not define) an exception class by the name of _type.

Intended to be used in header files.

See also:
nxs_exception_type

#define nxs_exception_define ( _parent,
_type   ) 

Defines an exception class _type inheriting from _parent.

Intended to be used in source files.

See also:
nxs_exception_type

#define nxs_exception_define_root ( _type   ) 

Defines an exception class _type that does not inherit from any other class.

Intended to be used in source files.

See also:
nxs_exception_type

#define nxs_raise ( _type,
_data   ) 

Raises a new exception of class _type.

If _data is not NULL, it is included with the exception for later handling.

See also:
nxs_exception_type

nxs_exception::data

#define nxs_rethrow ( _exception   ) 

Rethrows the nxs_exception pointed to by _exception.

This should be used instead of nxs_throw() to preserve backtrace information when catching an existing exception.

#define nxs_throw ( _exception   ) 

Throws the nxs_exception pointed to by _exception.

This does not preserve the values of the nxs_exception::func or nxs_exception::line fields, and should only be used with locally-created exceptions.

#define nxs_try

Begins a block of code that may throw exceptions.

 nxs_try {
      // code possibly raising exceptions goes here
      ...
 } nxs_catch_any (...) {
      ...
 }

Note:
It is legal to break out of a nxs_try block before any exceptions are thrown. Naturally, this will skip any exception handling.
Warning:
It is illegal to return from a nxs_try block or to exit its scope through the use of goto.


Function Documentation

void nxs_exception_cleanup ( void   ) 

Releases any resources associated with the exception module.

This should be called after all exception handling has finished, and when no more exceptions will be thrown.

Note:
For convenience, this function could be used with atexit().
See also:
nxs_exception_init

bool nxs_exception_init ( void   ) 

Initializes the exception module, returning true on success.

This should be called before any exception handlers are entered or any exceptions are thrown.

See also:
nxs_exception_cleanup

bool nxs_exception_is ( const struct nxs_exception exception,
const struct nxs_exception_type type 
)

Determines whether exception is of the exception class type, or a subclass thereof.

static void nxs_exception_print_trace ( const struct nxs_exception exception  )  [inline, static]

Unravels the backtrace of exception, listing all the functions it has passed through.


Variable Documentation

struct nxs_exception_type* const NXSAssertionFailureException

Thrown when a condition given to nxs_exception_assert() fails.

Inherits from NXSRootException.

struct nxs_exception_type* const NXSMemoryAllocationException

Thrown when memory cannot be allocated for internal exception handling data.

Inherits from NXSRootException.

struct nxs_exception_type* const NXSRootException

A basic root exception type.

This will not get thrown by NXS Toolkit code; however, a subtype may be.


Generated on Thu Dec 20 13:42:46 2007 for NXS Toolkit by  doxygen 1.5.4