Setjmp / longjmp and local variables

My questions are about the behavior of setjmp / longjmp regarding local variables.

Code example:

jmp_buf env; void abc() { int error; ... if(error) longjmp(env); } void xyz() { int v1; // non-volatile; changed between setjmp and longjmp int v2; // non-volatile; not changed between setjmp and longjmp volatile int v3; // volatile; changed between setjmp and longjmp volatile int v4; // volatile; not changed between setjmp and longjmp ... if(setjmp(env)) { // error handling ... return; } v1++; // change v1 v3++; // change v3 abc(); } int main(...) { xyz(); } 

The setjmp / longjmp documentation says:

"All available objects have values ​​since the call to longjmp () except that the values ​​of the objects of automatic storage time that are local to the function containing the call to the corresponding setjmp (), which are not of a variable type and which are changed between the call to setjmp () and longjmp () are undefined. "

I see the following two possible interpretations:

intepretation1:

Local variables are restored, except for those that are

  • non-volatile and
  • changed

intepretation2:

Local variables are restored except

  • those that are non-volatile and
  • those that are changed

According to interpretation1 after longjmp only v1 is undefined. v2, v3, v4. According to interpretation2, only v4 is defined after longjmp. v1, v2, v3 undefined.

Which one is right?

BTW: I need a generic ("portable") answer that is valid for all compilers, i.e. Trying with one specific compiler does not help.

+20
c
Sep 08 '09 at 11:21
source share
2 answers

Interpretation 1 is correct. If interpretation 2 was intended, the source code would use " or , which were changed" instead of "and".

+10
08 Sep '09 at 11:29
source share

setjmp / longjmp is implemented by saving registers (including stack and code pointers, etc.) during the first passage and restoring them when jumping.

In registers, and not on the stack, automatic (so-called local, stack) variables are stored that are not "mutable" can .

In these circumstances, longjmp will restore these register variables to their values ​​when setjmp () was first called.

In addition, a particularly smart compiler can avoid variables that can be inferred from the state of another variable and compute them on demand.

However, if the variable is automatic but not case-sensitive, it can be changed by code between setjmp and longjmp ..

Volatile explicitly tells the compiler not to store the variable in the register.

Therefore, unless you explicitly say that the variable is volatile, if you changed the variable between setjmp / longjmp, its value will depend on the choice the compiler makes, and therefore you should not rely on it ("undefined").

+26
08 Sep '09 at 11:29
source share



All Articles