setjmp
and longjmp
can be seen as a poor man's exception mechanism. BTW, Ocaml exceptions are as quick as setjmp
but have a much clearer semantics.
Of course a longjmp
is much faster than repeatedly returning error codes in intermediate functions, since it pops up a perhaps significant call stack portion.
(I am implicitly focusing on Linux)
They are valid and useful as long as no resources are allocated between them, including:
- heap memory (
malloc
)
fopen
-ing FILE*
handles
- opening operating system file descriptors (e.g. for sockets)
- other operating system resources, such as timers or signal handlers
- getting some external resource managed by some server, e.g. X11 windows (hence using any widget toolkit like GTK), or database handle or connection...
- etc...
The main issue is that that property of not leaking resources is a global whole-program property (or at least global to all functions possibly called between setjmp
and longjmp
), so it prohibits modular software development : any other colleague having to improve some code in any function between setjmp
and longjmp
has to be aware of that limitation and follow that discipline.
Hence, if you use setjmp
document that very clearly.
BTW, if you only care about malloc
, using systematically Boehm's conservative garbage collector would help a lot; you'll use GC_malloc
instead of malloc
everywhere and you won't care about free
, and practically that is enough; then you can use setjmp
without fears (since you could call GC_malloc
between setjmp
and longjmp
).
(notice that the concepts and the terminology around garbage collector are quite related to exception handling and setjmp
, but many people don't know them enough. Reading the Garbage Collection Handbook should be worthwhile)
Read also about RAII and learn about C++11 exceptions (and their relation to destructors). Learn a bit about continuations and CPS.
Read setjmp(3), longjmp(3) (and also about sigsetjmp
, siglongjmp
, and setcontext(3)) and be aware that the compiler has to know about setjmp