Setjmp.h
Encyclopedia
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
A typical use of
:
POSIX
.1 does not specify whether
— if a program employs signal handling it should use POSIX's
The C99 Rationale describes
s, flushing buffer
s, freeing heap-allocated memory, etc., do not occur.
If the function in which
Similarly, C99
does not require that
Compared to mechanisms in higher-level programming languages such as Python
, Java
, C++
, C#, and even pre-C languages such as Algol 60
, the technique of using
techniques, while languages such as Scheme, Smalltalk
, and Haskell
provide even more general continuation
-handling constructs.
When executed, the above program will output:
second
main
Notice that although the
by invoking
Following these rules can make it easier for the implementation to create the environment buffer, which can be a sensitive operation. More general use of
provides that
This is exploited by thread libraries to provide cooperative multitasking facilities without using
facilities. Whereas
Considering that
, is not required to be provided by C implementations, this mechanism may be portable where the
Since no exception will be generated upon overflow of one of the multiple stacks in such a mechanism, it is essential to overestimate the space required for each context, including the one containing
Header file
Some programming languages use header files. These files allow programmers to separate certain elements of a program's source code into reusable files. Header files commonly contain forward declarations of classes, subroutines, variables, and other identifiers...
defined in the C standard library
C standard library
The C Standard Library is the standard library for the programming language C, as specified in the ANSI C standard.. It was developed at the same time as the C POSIX library, which is basically a superset of it...
to provide "non-local jumps": control flow
Control flow
In computer science, control flow refers to the order in which the individual statements, instructions, or function calls of an imperative or a declarative program are executed or evaluated....
that deviates from the usual subroutine
Subroutine
In computer science, a subroutine is a portion of code within a larger program that performs a specific task and is relatively independent of the remaining code....
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 utilizes 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.Member functions
int setjmp(jmp_buf env) |
Sets up the local jmp_buf buffer and initializes it for the jump. This routine saves the program's calling environment in the environment buffer specified by the env argument for later use by longjmp . If the return is from a direct invocation, setjmp returns 0. If the return is from a call to longjmp , setjmp returns a nonzero value. |
void longjmp(jmp_buf env, int value) |
Restores the context of the environment buffer env that was saved by invocation of the setjmp routine in the same invocation of the program. Invoking longjmp from a nested signal handler is undefined. The value specified by value is passed from longjmp to setjmp . After longjmp is completed, program execution continues as if the corresponding invocation of setjmp had just returned. If the value passed to longjmp is 0, setjmp will behave as if it had returned 1; otherwise, it will behave as if it had returned value . |
setjmp
saves the current environment (i.e., the program state) at some point of program execution, into a platform-specific data structure (jmp_buf
) which can be used, at some later point of program execution, by longjmp
to restore the program state to that which was 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 or from a call to longjmp
. This leads to a common idiomProgramming idiom
A programming idiom is a means of expressing a recurring construct in one or more programming languages. Generally speaking, a programming idiom is an expression of a simple task or algorithm that is not a built-in feature in the programming language being used, or, conversely, the use of an...
:
if( setjmp(x) ){/* handle longjmp(x) */}
.POSIX
POSIX
POSIX , an acronym for "Portable Operating System Interface", is a family of standards specified by the IEEE for maintaining compatibility between operating systems...
.1 does not specify whether
setjmp
and longjmp
save or restore the current set of blocked signalsSignal (computing)
A signal is a limited form of inter-process communication used in Unix, Unix-like, and other POSIX-compliant operating systems. Essentially it is an asynchronous notification sent to a process in order to notify it of an event that occurred. When a signal is sent to a process, the operating system...
— if a program employs signal handling it should use POSIX's
sigsetjmp
/siglongjmp
.Member types
jmp_buf |
An array type, such as struct __jmp_buf_tag[1] , suitable for holding the information needed to restore a calling environment. |
The C99 Rationale describes
jmp_buf
as being an array type for backwards 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 viasetjmp
/longjmp
, normal "stack unwinding" does not occur and therefore, any required cleanup actions such as closing file descriptorFile descriptor
In computer programming, a file descriptor is an abstract indicator for accessing a file. The term is generally used in POSIX operating systems...
s, flushing buffer
Buffer (computer science)
In computer science, a buffer is a region of a physical memory storage used to temporarily hold data while it is being moved from one place to another. Typically, the data is stored in a buffer as it is retrieved from an input device or just before it is sent to an output device...
s, freeing heap-allocated memory, etc., do not occur.
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/corrupted stack frame.Similarly, C99
C99
C99 is a modern dialect of the C programming language. It extends the previous version with new linguistic and library features, and helps implementations make better use of available computer hardware and compiler technology.-History:...
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.Compared to mechanisms in higher-level programming languages such as Python
Python (programming language)
Python is a general-purpose, high-level programming language whose design philosophy emphasizes code readability. Python claims to "[combine] remarkable power with very clear syntax", and its standard library is large and comprehensive...
, Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
, C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
, C#, and even pre-C languages such as Algol 60
ALGOL 60
ALGOL 60 is a member of the ALGOL family of computer programming languages. It gave rise to many other programming languages, including BCPL, B, Pascal, Simula, C, and many others. ALGOL 58 introduced code blocks and the begin and end pairs for delimiting them...
, the technique of using
setjmp
/longjmp
to implement an exception mechanism is uninspiring. These languages provide more powerful exception handlingException handling
Exception handling is a programming language construct or computer hardware mechanism designed to handle the occurrence of exceptions, special conditions that change the normal flow of program execution....
techniques, while languages such as Scheme, Smalltalk
Smalltalk
Smalltalk is an object-oriented, dynamically typed, reflective programming language. Smalltalk was created as the language to underpin the "new world" of computing exemplified by "human–computer symbiosis." It was designed and created in part for educational use, more so for constructionist...
, and Haskell
Haskell (programming language)
Haskell is a standardized, general-purpose purely functional programming language, with non-strict semantics and strong static typing. It is named after logician Haskell Curry. In Haskell, "a function is a first-class citizen" of the programming language. As a functional programming language, the...
provide even more general continuation
Continuation
In computer science and programming, a continuation is an abstract representation of the control state of a computer program. A continuation reifies the program control state, i.e...
-handling constructs.
Simple example
This example shows the basic idea of setjmp. Main calls first, which in turn calls second. The "second" function jumps back into main, skipping "first"'s print statement.When executed, the above program will output:
second
main
Notice that although the
first
subroutine gets called, "first
" never is 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 SpecificationSingle UNIX Specification
The Single UNIX Specification is the collective name of a family of standards for computer operating systems to qualify for the name "Unix"...
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)
Following these rules can make it easier for the implementation to create the environment buffer, which can be a sensitive operation. More general use of
setjmp
can cause undefined behaviour, such as corruption of local variables; conforming compilers and environments are not required to protect or even warn against such usage. However, slightly more sophisticated idioms such as switch ((exception_type = setjmp(env))) { }
are common in literature and practice, and remain relatively portable. A simple conforming methodology is presented below, where an additional variable is maintained along with the state buffer. This variable could be elaborated into a structure incorporating the buffer itself.Cooperative multitasking
C99C99
C99 is a modern dialect of the C programming language. It extends the previous version with new linguistic and library features, and helps implementations make better use of available computer hardware and compiler technology.-History:...
provides that
longjmp
is guaranteed to work only when the destination is a calling function, i.e., that the destination scope is guaranteed to be intact. Jumping to a function that has already terminated by return
or longjmp
is undefined. However, most implementations of longjmp
do not specifically destroy local variables when performing the jump. Since the context survives until its local variables are erased, it could actually be restored by setjmp
. In many environments (such as Really Simple Threads and TinyTimbers), idioms such as if(!setjmp(child_env)) longjmp(caller_env);
can allow a called function to effectively pause-and-resume at a setjmp
.This is exploited by thread libraries to provide cooperative multitasking facilities without using
setcontextSetcontextsetcontext is one of a family of C library functions used for context control. The setcontext family allows the implementation in C of advanced control flow patterns such as iterators, fibers, and coroutines...
or other fiberFiber (computer science)
In computer science, a fiber is a particularly lightweight thread of execution.Like threads, fibers share address space. However, fibers use co-operative multitasking while threads use pre-emptive multitasking. Threads often depend on the kernel's thread scheduler to preempt a busy thread and...
facilities. Whereas
setcontext
is a library service which can create an execution context in heap-allocated memory and can support other services such as buffer overflow protection, abuse of setjmp
is implemented by the programmer, who may reserve memory on the stack and fail to notify the library or operating system of the new operating context. On the other hand, a library's implementation of setcontext
may internally use setjmp
in a fashion similar to this example to save and restore a context, after it has been initialised somehow.Considering that
setjmp
to a child function will generally work unless sabotaged, and setcontext
, as part of POSIXPOSIX
POSIX , an acronym for "Portable Operating System Interface", is a family of standards specified by the IEEE for maintaining compatibility between operating systems...
, is not required to be provided by C implementations, this mechanism may be portable where the
setcontext
alternative fails.Since no exception will be generated upon overflow of one of the multiple stacks in such a mechanism, it is essential to overestimate the space required for each context, including the one containing
main
and including space for any signal handlers that might interrupt regular execution. Exceeding the allocated space will corrupt the other contexts, usually with the outermost functions first. Unfortunately, systems requiring this kind of programming strategy are often also small ones with limited resources.