The C Reference Manual, Appendix B describes two functions setjmp
and longjmp
for something called non-local jumps. Apart from the basic understanding that setjmp
saves the state information and longjmp restores the state
, I haven't been able to understand the exact flow and use cases for this feature.
So, what exactly does this feature accomplish and where is it useful?
As for the control flow: setjmp
returns twice, and longjmp
never returns. When you call setjmp
for the first time, to store the environment, it returns zero, and the when you call longjmp
, the control flow passes to return from setjmp
with the value provided in the argument.
(Note that setjmp
needn't actually be functions; it may well be a macro. longjmp
is a function, though.)
Use cases are generally cited as "error handling", and "don't use these functions".
Here's a little control flow example:
jmp_buf env;
void foo()
{
longjmp(&env, 10); +---->----+
} | |
| |
int main() (entry)---+ ^ V
{ | | |
if(setjmp(&env) == 0) | (= 0) | | (= 10)
{ | ^ |
foo(); +---->----+ |
} +---->----+
else |
{ |
return 0; +--- (end)
}
}
Notes:
You cannot pass 0 to longjmp
. If you do, 1
is returned by setjmp
.
You must not return from the function that called setjmp
before the corresponding longjmp
. In other words, longjmp
must only be called above setjmp
in the call stack.
(Thanks to @wildplasser:) You cannot actually store the result of setjmp
. If you want to return in several different ways, you can use a switch
, though:
switch (setjmp(&env))
{
case 0: // first call
case 2: // returned from longjmp(&env, 2)
case 5: // returned from longjmp(&env, 5)
// etc.
}