In my understanding, a typical usage of setjmp()
and longjmp()
is exception handling (usage in libpng
should be a famous example of that) and there will be at most one call of longjmp()
for one setjmp()
call.
Is it safely allowed to do longjmp()
multiple times for one setjmp()
call like this?
#include <stdio.h>
#include <setjmp.h>
jmp_buf jb;
int i;
int main(void) {
i = 0;
setjmp(jb);
printf("%d\n", i);
i++;
if (i < 10) longjmp(jb, 1);
return 0;
}
0
1
2
3
4
5
6
7
8
9
I successfully got the expected output from this execution, but is this guaranteed?
Or will jmp_buf
invalidated when longjmp()
is once used for that?
setcontext - Wikipedia says "They may be viewed as an advanced version of setjmp/longjmp; whereas the latter allows only a single non-local jump up the stack", but I didn't find descriptions that disallow multiple usage of longjmp()
like this from N1570 7.13 Nonlocal jumps <setjmp.h>.
I know that using setjmp()
and longjmp()
is discouraged, but I am wondering if they can be used as a workaround when using loop statements (for
, while
, do-while
) and goto
statements is banned but using setjmp()
and longjmp()
is not banned in some programming quiz.
(using recursion may be answers for this type of quiz, but it has risk of stack overflow when trying to deal with large data that require many iterations)
It is possible to construct a strictly conforming program that calls
longjmp()
multiple times to return to the point of the samesetjmp()
call. It comes down to the state of the abstract machine, including memory contents, and especially the state of thejmp_buf
in which asetjmp()
call records the state required to return to the point of that call. The standard specifies that(C2018 7.13.2.1/3)
In particular, that means that the
longjmp()
call must not change the value of thejmp_buf
from which it gets its information, and there cannot be any hidden state elsewhere thatlongjmp()
could update to mark the correspondingsetjmp()
as being used up. If machine state permits a conforminglongjmp()
call, then an equivalentlongjmp()
call must still be conforming after the resulting second (or third, etc.) return from the correspondingsetjmp()
call.