Non–local exits are a way to transfer execution from one point to another in a program; they are
implemented by the standard C library through the setjmp() and longjmp() functions.
CCExceptions uses the POSIX variants sigsetjmp() and siglongjmp(): they do
not save the interprocess signals mask, making the operations a bit faster.
The main usage pattern for this module is the following:
cce_location_t L[1];
if (cce_location(L)) {
/* handle the exception here */
cce_run_catch_handlers_final(L);
} else {
/* do something useful here */
cce_run_body_handlers(L);
}
it is usually useful to define variables of type cce_location_t as one–element arrays.
When using CCExceptions we should consider configuring our source code editor to automatically
insert this code template.
All the following definitions are accessible from the header file ccexceptions.h.
Struct type representing the location context. This type is “derived” from sigjmp_buf
in the sense that a pointer to cce_location_t is also a pointer to sigjmp_buf.
Instances of this structure reference an instance of type cce_condition_t; it is set by
cce_raise(). The client code is responsible for releasing resources associated to this value
by retrieving a pointer to it with cce_condition() and releasing it with
cce_condition_delete().
Before terminating the use of instances of this type we must always call
cce_run_body_handlers(), cce_run_catch_handlers(). We must assume that the handlers
might access the cce_condition_t object, so: first we call the handlers, then we release
the exceptional–condition object.
The functions cce_run_catch_handlers_final() or cce_run_catch_handlers_raise() will run
the catch handlers and take care of handling the cce_condition_t object.
Pointer to cce_location_t.
Initialise the location L, but do not call sigsetjmp(). We are not meant to
call this function directly; rather we should use the macro cce_location().
Initialise the location L; call sigsetjmp() and return its return value.
Constants used by the library as non–local exit codes. They are defined as 0 and represent
the return value of cce_location() at the first evaluation.
This code represents the return value of the setjmp() evaluation after a cce_retry()
call.
Constants used by the library as non–local exit codes. They are defined as 1 and are the
return value of cce_location() when a non–local exit is performed by cce_raise().
Raise an exception associated to the location L, with exceptional–condition object referenced
by C. This function performs the call to siglongjmp() with code CCE_EXCEPT.
With a call to this function: the client code is put in charge of releasing resources associated to
C. If C is NULL: an internal, statically allocated, exceptional–condition object
is selected to represent an “unknown exceptional condition”; we can transparently apply the
function cce_condition_delete() to this object.
Jump back to the location L, reentering the body of the construct.
Return the exceptional–condition object associated to the location L; this value is
never NULL.
If we apply this function to a location without calling cce_raise(): the returned pointer
references an internal, statically allocated, exceptional–condition object representing an
“unknown exceptional condition”; we can transparently apply the function
cce_condition_delete() to this object.
As examples of logic, consider the following:
cce_location_t L[1];
if (cce_location(L)) {
/* handle the exception here */
cce_run_catch_handlers_final(L);
} else {
/* do something useful here */
cce_run_body_handlers(L);
}
void
outer (void)
{
cce_location_t L[1];
if (cce_location(L)) {
/* handle the exception here */
cce_run_catch_handlers_final(L);
} else {
inner(L);
cce_run_body_handlers(L);
}
}
void
inner (cce_location_t * upper_L)
{
cce_location_t L[1];
if (cce_location(L)) {
cce_run_catch_handlers_raise(upper_L, L);
} else {
/* do something useful here */
cce_run_body_handlers(L);
}
}
This document describes version 0.9.0-devel.3 of CCExceptions.