longjmp -- Restore Stack Environment

Format

#include <setjmp.h>
void longjmp(jmp_buf env, int value);

Language Level: ANSI, POSIX, XPG4
longjmp restores a stack environment previously saved in env by setjmp. setjmp and longjmp provide a way to perform a nonlocal goto. They are often used in signal handlers.

A call to setjmp causes the current stack environment to be saved in env. A subsequent call to longjmp restores the saved environment and returns control to a point in the program corresponding to the setjmp call. Execution resumes as if the setjmp call had just returned the given value.

All variables (except register variables) that are accessible to the function that receives control contain the values they had when longjmp was called.

On both OS/2 and Windows, the values of variables that are allocated to registers by the compiler are unpredictable. Because any auto variable could be allocated to a register in optimized code, you should consider the values of all auto variables to be unpredictable after a longjmp call.

Notes:

  1. Ensure that the function that calls setjmp does not return before you call the corresponding longjmp function. Calling longjmp after the function calling setjmp returns causes unpredictable program behavior.
  2. The value argument must be nonzero. If you give a zero argument for value, longjmp substitutes 1 in its place.
  3. When you call setjmp in a C++ program, on OS/2 and Windows, ensure that that part of the program does not also create C++ objects that need to be destroyed. When you call longjmp, objects existing at the time of the setjmp call will still exist, but any destructors called after setjmp are not called.

Return Value
longjmp does not use the normal function call and return mechanisms; it has no return value.

Example (C++ setjmp/longjmp Restriction)
Given the following program:

#include <stdio.h>
#include <setjmp.h>
class A {
   int i;
   public:
      A(int I) {i = I; printf("Constructed at line %d\n", i);}
      ~A() {printf("Destroying object constructed at line %d\n",i);}
   };
jmp_buf jBuf;
int main(void) {
   A a1(__LINE__);
   if (!setjmp(jBuf)) {
     A a2(__LINE__);
     printf("Press y (and Enter) to longjmp; anything else to return norm
     char c = getchar();
     if (c == 'y')
        longjmp(jBuf, 1);
   }
   A a3(__LINE__);
   return 0;
}

If you return normally, the output would be:

Constructed at line 13
Constructed at line 15
Press y (and Enter) to longjmp; anything else to return normally
x
Destroying object constructed at line 15
Constructed at line 21
Destroying object constructed at line 21
Destroying object constructed at line 13

If you called longjmp, the output would be:

Constructed at line 13
Constructed at line 15
Press y (and Enter) to longjmp; anything else to return normally
y
Constructed at line 21
Destroying object constructed at line 21
Destroying object constructed at line 13

Notice that the object from line 15 is not destroyed.

Example (longjmp -- Restore Stack Environment)



setjmp -- Preserve Environment
<setjmp.h>