libxcpc
(Exception and resource handling in C)
The
libxcpc
library implements an automatic resource cleanup and exception handling
in
C.
Error handling and cleanup code (at least for code that
does
error handling) can take quite some space in terms of lines of code to
be
written. This not only increases the binary size, but makes the code
more
difficult to read.
Furthermore, error handling code typically lies in untested code paths (because
they get exercised only when abnormal conditions happens) that are very much error
prone.
Effective and complete code coverage tests to exercise all error paths, are not trivial
to implement, and very often many of such paths are simply left untested.
C++
has native exception handling, and this solves part of the problem,
while
keeping exposed the resource cleanup one.
The
libxcpc
offers
C++
like exception handling, plus automatic resource cleanup, to be used in
software written in
C.
The
libxcpc
introduces three abstractions, that are
Resource,
Container
and
Exception.
The
Resource
is every object (or action) that needs cleanup. This can be a block of
allocated memory, an open file, a mapped memory region, etc...
Every allocated
Resource
is owned by a
Container.
A
Resource
can be moved from a
Container
to another.
A
Container
is a bucket inside which
Resource
are allocated.
A
Container
can be the parent of other
Containers,
by hence introducing a parent/child relationship between
Containers.
A
Container
can be reassigned to be child of a new
Container.
By freeing a
Container
all the
Resources
allocated inside the
Container
will be freed, and all the child
Containers
will be recursively freed too.
Resource
Containers
greatly simplify the resource cleanup code, by being able to issue a
single
call to free a
Container
and having automatically all the
Resources
contained by it, freed as well.
Resources
are added/removed in a
LIFO
(Last In First Out) way, and the
libxcpc
library offers APIs to re-arrange the order of the
Resources
inside their
Contexts.'
An
Exception
is (like in
C++)
any kind of abnormal condition that prevent the program to flow in its
path.
This can be a failed memory allocation, a failure to open a file, a
failure
to
mmap(2)
a portion of a file, a failure to
write(2)
a file, etc...
An
Exception
is described by a unique number
(int)
and by an associated data
(void *).
Exceptions
are thrown using the
XCPC_THROW(ctx, exno, data)
statement, or re-thrown using
XCPC_RETHROW(ctx).
A nice feature of exception handling, is that it allows you to handle
only
certain kind of exceptions, and different exceptions in different
points
of your code tree.
Using
libxcpc
library, you handle exceptions by surrounding the potentially-throwing
code with the
XCPC_TRY(ctx)
statement.
The code can then use either the
XCPC_CATCH(exno)
or the
XCPC_CATCH_ANY
statements to handle specific or all kind of exceptions that happened
in the
code bound by the
XCPC_TRY(ctx).
An
Exception
block must be terminated by a
XCPC_END_TRY
statement.
If the current
Exception
block does not handle the current
Exception
using the
XCPC_CATCH(exno)
statement, and does not have a
XCPC_CATCH_ANY
statement, the
libxcpc
library backtrack to find a valid handler in the code at higher layers
of
the call hierarchy.
It is important that at least the other
Exception
block uses a
XCPC_CATCH_ANY
statement, so that any
Exceptions
not caught by the code, is handled properly.
When an
Exception
is caught by an handler, all the resources allocated by the code from
the
beginning of the
XCPC_TRY(ctx)
block, down to the place where the
Exception
is thrown, are automatically freed once the handler reaches the
XCPC_END_TRY
statement.
Documentation
The
libxcpc library man page
is available :
HTML TXT PDF
License and
Software
The libxcpc library
is made available through the GNU LGPL license
together with the complete sources. Please read carefully the license before
using
the software. The latest library package is available here :
Version
0.21