It is somewhat useless to use setjmp()
and longjmp()
in data processing situations. So, this would be the case where you might be concerned with automatic variables. The variables can be in a stack slot or a register. If they are in a stack slot, the stack is not restored by popping contexts along the stack. Instead, the stack is immediately rewound and callee saved registers are restored.
The stack space used by the routine is reserved and other routines should not use it. So if the compiler is aware that the variable is stored on the stack before (setjmp()
), then it can retrieve it on return. It will just confound analysis, which is based on 'basic blocks' and setjmp()/longjmp()
defy that categorization.
I would question why anyone would use setjmp()/longjmp()
in this context. A good use might be found in libjpeg and another by Simon Tatham use in co-routines. Ie, the routines are rather single purposed. They either setup a context for a long running operation that might have many exceptional conditions or they are used as a primitive scheduler. Mixing actual data processing with them is a mistake waiting to happen (for all the reason mentioned elsewhere).
Subclause 7.13.1.1 of the C Standard spells out where you can use setjmp()
. It is an abnormal function, so treating it like a normal function call is the main issue. Perhaps the language should have gave it a different syntax.
Also what is meant by the statement, "The longjmp() routines may not be called after the routine which called the setjmp() routines returns."
Here is an example in function e()
,
jmp_buf buf; // Another reason to avoid static/globals here.
void k(void) {
/* ... */
longjmp(buf, 1);
}
void f(void) {
if (setjmp(buf) == 0) {
k();
} else {
/* longjmp was invoked */
}
}
void e(void) {
f();
longjmp(buf, 1); // ERROR! we will return to f(); popped stack slot.
// If 'buf' wasn't global, but declared in f(), this would not compile
// That is a good thing.
}
The code sequence is e() -> f() -> k() -> f() -> e() -> crash.
It is somewhat like using a closed file handle. Ie, the jmp_buf is still set to valid looking values, but they point to non-existent stack.