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 correspondingsetjmp
macro that do not havevolatile
-qualified type and have been changed between thesetjmp
invocation andlongjmp
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.