Non-local Jumps (setjmp(), longjmp())
The C functions setjmp()
and longjmp()
provide the ability to perform non-local jumps. A non-local jump is a jump in code execution between two separate functions. This is opposed the the local jump, goto which can perform jumps as long as you stay within the same function.
Non-local jumps have complications, as the stack needs to be saved/modified when switching context between two separate functions.
Definitions
setjmp()
and longjmp()
are defined as:
setjmp()
is used to declare a place you want to jump back to at some future point in time. setjmp()
takes a jmp_buf
type variable as it’s input. This jmp_buf
is used to save the state of the stack.
setjmp()
has to be called before longjmp()
.
What Do I Need To Include?
setjmp()
and longjmp()
are both defined in setjmp.h.
Making Your Own Exception Handlers In C
A cool feature about setjmp()
and longjmp()
is that they can be used to make your own exception handling in C. If you have use any higher-level, OOP languages before, you may be familiar with the notion of an exception handler, using the try/catch/throw keywords (or similar) that allow you to run “may not work” code and catch any errors that may occur.
C does not have native exception support, but you can make your own with some clever use of setjmp()
, longjmp()
and preprocessor macros.
This basic example does not have any support for differing exception types.
Note that this primitive form of exception handling does not come with all advanced functionality you get with higher-level languages. For example, higher-level languages will automatically de-allocate memory when an object’s constructor throws an exception (not that you have objects in C anyway).
If you are interested in this and still want more information, see http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html for a basic implementation. http://www.on-time.com/ddj0011.htm also has some nice explanations and worked tutorial code.
https://code.google.com/p/exceptions4c/ is a C-based exception library.
A Word Of Caution To C++ Users
The C standard for the setjmp()
and longjmp()
functions makes no assurances that the destructors will be called for objects that are created after setjmp()
(aka TRY
) and before longjmp()
(aka CATCH
) (essentially the portion of code that will be “unwound”). In fact, the behaviour in these cases is undefined.
Therefore, these functions can be very dangerous to use in C++, causing unexpected behaviour and memory leaks. I once investigated the use of these functions as a replacement for the traditional exceptions for embedded microcontrollers, but ruled it out due to this issue.