What are setjmp
and longjmp
in C?
Normal program flow in C follows function calls and branching constructs (if
, while
etc). The functions setjmp
and longjmp
introduce another kind of program flow.
#include <setjmp.h>
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);
In its simplest use, the process calls setjmp
somewhere, then at some time later calls longjmp
. Roughly, the call to longjmp
restores the process in the state that it existed when it called setjmp
. Thus, this program is an infinite loop:
#include <setjmp.h>
#include <stdio.h>
jmp_buf buf;
int main(void) {
int r = setjmp(buf);
printf("r = %d\n", r);
longjmp(buf, 42);
return 0;
}
... which prints:
% ./a.out
r = 0
r = 42
r = 42
r = 42
r = 42
r = 42
r = 42
...
This loops forever, since the process state at setjmp
led to the call to longjmp
. Thus, the process makes the calls setjmp
, longjmp
, longjmp
, longjmp
, ad infinitum. (Actually, I think this pattern causes undefined behavior. The setjmp
and longjmp
calls are supposed to come in pairs.)
The program needs a way, immediately after the setjmp
call, to determine whether it just set the jump or it had its state restored. The return value of setjmp
provides this. After a normal call to setjmp
, it returns 0
. When the state is restored after a longjmp
, the return value is provided by the longjmp
call; this is what the second argument to longjmp
provides. So this program does not infinite loop:
#include <setjmp.h>
#include <stdio.h>
jmp_buf buf;
int main(void) {
switch (setjmp(buf)) {
case 0:
printf("I just set jump\n");
longjmp(buf, 42);
break;
case 42:
printf("Returned from longjmp\n");
break;
default:
fprintf(stderr, "We shouldn't get here!\n");
}
return 0;
}
This prints:
% ./a.out
I just set jump
Returned from longjmp
The man
page says that setjmp
“saves its calling environment” in buf
, and longjmp
“restores the environment”. It’s a bit vague on what that “environment” is, though. Let’s find out in a future post.
This page copyright James Fisher 2017. Content is not associated with my employer.