Setjmp/longjmp
From Wikipedia, the free encyclopedia
- The correct title of this article is setjmp/longjmp. The initial letter is capitalized due to technical restrictions.
setjmp and longjmp are paired C library functions intended for use in non-local control flow and exception handling.
setjmp saves the current execution state into a structure of type jmp_buf; later, a longjmp call can transfer control to the point immediately after the call to setjmp. The (apparent) return value from setjmp indicates whether control reached that point normally or from a call to longjmp; this allows the use of a common idiom, placing the setjmp in the condition of an if/else block, similar to that with the fork system call.
The typical use for setjmp/longjmp is for exception handling; by calling longjmp, the program can jump out of many levels of nested function calls without having to go to the trouble of setting flag variables which need to be checked in each function. A problem with the use of setjmp/longjmp is that cleanup (closing file descriptors, flushing buffers, freeing memory, etc.) will not be conducted.
setjmp/longjmp do not save or restore the current set of blocked signals; if a program employs signal handling it should use sigsetjmp/siglongjmp.
Compared to mechanisms in higher-level programming languages such as Java, C#, and particularly in older high-level languages such as Algol 60 and Common Lisp, the setjmp/longjmp technique is archaic. These languages provide far more powerful exception handling techniques.
Syntax
int setjmp(jmp_buf env); void longjmp(jmp_buf env, int val); /* setjmp returns (val != 0 ? val : 1) */
Examples
A function which returns abnormally via non-local control flow:
#include <stdio.h>
#include <setjmp.h>
/* Global "environment" variable; this must be in scope if longjmp is to be called. */
jmp_buf g_env;
/* A function that exits abnormally via longjmp */
void function(void){
printf("(calling longjmp)\n");
longjmp(g_env,1);
printf("This is not reachable because of the longjmp above.\n");
}
int main(int argc, char *argv[])
{
int i = setjmp(g_env);
/* This is where execution resumes when longjmp is called: */
printf("i after setjmp: %d\n",i);
/* setjmp returns 0 only when it is first called; never after a longjmp */
if(i==0){
printf("(calling function)\n");
function();
printf("This is never reached!\n");
}
return 0;
}
Simple iteration, this program will print its message 10 times, from 0 through 9. Note that the initial call to setjmp returns 0, and subsequent return values are the second argument to longjmp:
#include <stdio.h>
#include <setjmp.h>
int
main(int argc, char *argv[])
{
jmp_buf env;
int i = setjmp(env);
while (i < 10) {
printf("calling longjmp(env, %d)\n", i);
longjmp(env, ++i);
}
return 0;
}
See also
- setcontext et al

