#include <setjmp.h>
#include <stdio.h>
jmp_buf jmp;
int test() {
setjmp(jmp);
puts("Birds are crying");
return 0;
}
int main() {
longjmp(jmp,1);
return 0;
}
Above code doesn't work and crashes, why?
I am using the GCC compiler on Windows 10 Pro.
Your usage of longjmp()
is invalid, take a look at the documentation:
longjmp()
restores the environment saved by the last call ofsetjmp()
You need to call setjmp()
first in order to "set" where to jump before calling longjump()
. That's why your code doesn't work. It's undefined behavior at best.
In other words, you cannot just use longjmp()
as a simple "jump to global label". It has a different purpose.
after putting
test();
call before the linelongjmp
it works and print it twice but why does it still crashes?
Let's again take a look at the documentation:
setjmp()
saves the stack context/environment in env for later use bylongjmp()
. The stack context will be invalidated if the function which calledsetjmp()
returns.
You cannot longjmp()
to a buffer that was previously set by a function that has now returned. It's invalid. Your usage of setjmp()
/longjmp()
is really not what those functions are meant for.
Jumping out to another function isn't really the purpose of setjmp()
/longjmp()
, their purpose is to save the context and "jump back" to a function that has still not returned (see below example). It's not simple to come up with a meaningful example usage of such functions, since they are meant for advanced usage.
Here's a correct usage example (while still not that meaningful) from Wikipedia:
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
void second() {
printf("second\n"); // prints
longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1
}
void first() {
second();
printf("first\n"); // does not print
}
int main() {
if (!setjmp(buf))
first(); // when executed, setjmp returned 0
else // when longjmp jumps back, setjmp returns 1
printf("main\n"); // prints
return 0;
}