setjmp.h is a header defined in the C standard library to provide "non-local jumps": control flow that deviates from the usual subroutine call and return sequence. The complementary functions setjmp and longjmp provide this functionality.

A typical use of setjmp/longjmp is implementation of an exception mechanism that exploits the ability of longjmp to reestablish program or thread state, even across multiple levels of function calls. A less common use of setjmp is to create syntax similar to coroutines.

Setjmp.h

Member functions

setjmp saves the current environment (the program state), at some point of program execution, into a platform-specific data structure (jmp_buf) that can be used at some later point of program execution by longjmp to restore the program state to that saved by setjmp into jmp_buf. This process can be imagined to be a "jump" back to the point of program execution where setjmp saved the environment. The (apparent) return value from setjmp indicates whether control reached that point normally (zero) or from a call to longjmp (nonzero). This leads to a common idiom: if( setjmp(x) ){ /* handle longjmp(x) */}.

Setjmp.h

POSIX.1 does not specify whether setjmp and longjmp save and restore the current set of blocked signals; if a program employs signal handling it should use POSIX's sigsetjmp/siglongjmp.

Setjmp.h

Member types

The C99 Rationale describes jmp_buf as being an array type for backward compatibility; existing code refers to jmp_buf storage locations by name (without the & address-of operator), which is only possible for array types.

Caveats and limitations

When a "non-local goto" is executed via setjmp/longjmp in C++, normal "stack unwinding" does not occur. Therefore, any required cleanup actions will not occur either. This could include closing file descriptors, flushing buffers, or freeing heap-allocated memory.

If the function in which setjmp was called returns, it is no longer possible to safely use longjmp with the corresponding jmp_buf object. This is because the stack frame is invalidated when the function returns. Calling longjmp restores the stack pointer, which—because the function returned—would point to a non-existent and potentially overwritten or corrupted stack frame.

Similarly, C99 does not require that longjmp preserve the current stack frame. This means that jumping into a function which was exited via a call to longjmp is undefined. However, most implementations of longjmp leave the stack frame intact, allowing setjmp and longjmp to be used to jump back-and-forth between two or more functions—a feature exploited for multitasking.

Example usage

Simple example

The example below shows the basic idea of setjmp. There, main() calls first(), which in turn calls second(). Then, second() jumps back into main(), skipping first()'s call of printf().

#include <stdio.h>

#include <setjmp.h>

static jmp_buf buf;

void second() {

printf("second\n"); // prints

longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1 }

void first() {

second(); printf("first\n"); // does not print }

int main() {

if (!setjmp(buf)) first(); // when executed, setjmp returned 0 else // when longjmp jumps back, setjmp returns 1 printf("main\n"); // prints

return 0; }

When executed, the above program will output:

second

main

Notice that although the first() subroutine gets called, "first" is never printed. "main" gets printed as the conditional statement if (!setjmp(buf)) is executed a second time.

Exception handling

In this example, setjmp is used to bracket exception handling, like try in some other languages. The call to longjmp is analogous to a throw statement, allowing an exception to return an error status directly to the setjmp. The following code adheres to the 1999 ISO C standard and Single UNIX Specification by invoking setjmp in a limited range of contexts: As the condition to an if, switch or iteration statement As above in conjunction with a single ! or comparison with an integer constant As a statement (with the return value unused)