Home > Enterprise >  Using setjmp and longjmp with a local jmp_buf
Using setjmp and longjmp with a local jmp_buf

Time:05-10

Is it possible for setjmp or longjmp to modify the contents of the local jmp_buf that would cause its contents to be undefined when setjmp returns from a longjmp?


As an academic exercise, I was attempting to use setjmp as a substitute for goto. To keep the loop replacement local to the function, the jmp_buf used is also a local variable.

void foo (int n) {
    jmp_buf jb;
    volatile int i;
    i = setjmp(jb);
    if (i < n) {
        do_stuff(i);
        longjmp(jb,   i);
    }
}

I understand that non-volatile local variables that have been modified between the setjmp call and the longjmp call are unspecified after longjmp. However, I was curious about the local jmp_buf variable itself. It is unclear if longjmp itself can be considered something that may modify the local jmp_buf variable, and whether this means its contents are unspecified when setjmp returns after the call to longjmp.

If I need to be concerned about it, I can create a volatile copy of the jmp_buf and copy its contents around. But, I'd like to avoid that if it isn't required.

CodePudding user response:

That's fine.

On a related note, you don't need volatile on i because it's assigned to by setjmp().

On a very careful reading of the man page for longjmp() and my copy of K&R C, the contents of jb are only invalid within the body of your function, meaning if there were a second call to longjmp(), it would see a valid view of jb. Under the resaonable assumption that valid code does not become invalid in newer standard versions, this will still apply today.

TL;DR you don't need to mark variables of type jmp_buf volatile.

CodePudding user response:

The C11 standard section §7.13.2.1 point 3 states:

All accessible objects have values, and all other components of the abstract machine have state, as of the time the longjmp function was called, except that the values of objects of automatic storage duration that are local to the function containing the invocation of the corresponding setjmp macro that do not have volatile-qualified type and have been changed between the setjmp invocation and longjmp call are indeterminate.

Your jmp_buf object is not changed between setjmp(jb) and longjmp(jb, i). The only variable which is changed between the calls is i, which is declared volatile, as the standard suggests.

So, to answer your question, longjmp cannot by itself "modify the contents of the local jmp_buf [in such a way] that would cause its contents to be undefined when setjmp returns", but modifying the jmp_buf between the two calls through other means could definitely cause trouble.

  • Related