setjmp


setjmp

Saves the calling environment as a long jump destination

 #include <setjmp.h> int setjmp ( jmp_buf env  ); 

The setjmp( ) macro saves the current environment at the time of the call in a buffer specified by its argument. The environment includes the stack, and with it all variables that have automatic storage duration. Like the setjmp( ) macro itself, the argument's type, jmp_buf, is defined in the header file setjmp.h.

A later call to the longjmp( ) function restores the saved environment. As a result, the longjmp( ) function does not return, but instead causes execution to continue as if control had returned from the setjmp( ). However, while the original setjmp( ) call always returns 0, the apparent return value after longjmp( ) is never equal to zero.

Because the execution environment saved may not include other partial expressions, the return value of setjmp( ) must not be used except in simple conditional expressions, or in comparison to an integer constant value. Furthermore, if any variables with automatic storage duration in the function that called setjmp( ) were modified after the setjmp( ) call (and were not declared as volatile), then their values after the longjmp( ) call are indeterminate.

Example

This example shows the complete contents of two source files to illustrate how setjmp( ) and longjmp( ) allow you to escape from a function call.

 #include <stdlib.h> #include <stdio.h> #include <setjmp.h> #include <errno.h> double calculate1( double x);      // Functions defined double calculate2( double x);      // in calculate.c. jmp_buf jmp_dest;                  // Destination for longjmp( ) int main( ) {   double x = 0, y1, y2;   int n = 0;   puts("--- Demonstrating non-local jumps ---\n");   switch( setjmp( jmp_dest))     // Jump to here for error handling   {   case 0:                        // The original setjmp( ) call     break;   case EDOM:                     // Arrived via longjmp( ) call with EDOM     puts("Domain error. "          "Negative numbers are not permitted.");     break;   case ERANGE:                   // Arrived via longjmp( ) call with ERANGE     puts("Range error. "          "The number you entered is too big.");     break;   default:                       // We should never arrive here.     puts("Unknown error.");     exit( EXIT_FAILURE );   }   printf("Enter a number: ");   do   {     if ( (n = scanf("%lf", &x)) < 0)      // Read in a number.        exit( EXIT_FAILURE );              // Read end of file.     while ( getchar( ) != '\n')               // Clear the input buffer.       ;     if ( n == 0 )        printf("Invalid entry. Try again: ");   }while ( n == 0 );   y1 = calculate1(x);   y2 = calculate2(x);   printf("\nResult of Calculation 1: %G\n", y1);   printf(  "Result of Calculation 2: %G\n", y2);   return 0; } // calculate.c: Perform some calculations. // Functions: calculate1( ), calculate2( ). #include <math.h> #include <setjmp.h> #include <errno.h> extern jmp_buf jmp_dest;                  // Destination for longjmp( ) double calculate1( double x) {   if ( x < 0)     longjmp( jmp_dest, EDOM);        // Domain error   else     return sqrt(x); } double calculate2( double x) {   double y = exp(x);   if ( y == HUGE_VAL)     longjmp( jmp_dest, ERANGE);      // Range error   else     return y; } 

See Also

longjmp( )



C(c) In a Nutshell
C in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596006977
EAN: 2147483647
Year: 2006
Pages: 473

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net