typedef long int jmp_buf[JMP_BUF_SIZE];The type jmp_buf ought to be a structure or record type, but in C, declaring it as an array allows instances to be statically instantiated while at the same time allowing objects of type jmp_buf to be implicitly passed by reference instead of by value, as would happen for any other standard type in C. This is an awful feature of the C language, we use it here to conform with the standard definition of jmp_buf. Therefore, fields in what ought to be a record will be given by constant offsets into the array:
#define JMP_BUF_RA 0 -- the return address #define JMP_BUF_FP 1 -- the saved frame pointer #define JMP_BUF_SIZE 2The above description is absolutely minimal! With this, we can write the following code:
int setjmp( jmp_buf b ) { long int * h; -- a handle on the local variables; h = &h + RA_OFFSET; -- h points to the return address; b[JMP_BUF_RA] = *h; h = &h + FP_OFFSET; -- h points to the saved frame pointer; b[JMP_BUF_FP] = *h; return 0; } int longjmp( jmp_buf b, int v ) { long int * h; -- a handle on the local variables; h = &h + RA_OFFSET; -- h points to the return address; *h = b[JMP_BUF_RA]; h = &h + FP_OFFSET; -- h points to the saved frame pointer; *h = b[JMP_BUF_FP]; return v; }This version will only work if nothing in registers needs to be saved between setjmp and longjmp. Thus, if setjmp is called as a statement, it should work, but if it is called from within an expression where the results of evaluating other terms of the expression were saved in registers, it will not work because these values will be lost.