setjmp is used to place the marker where the longjump call should return, it returns 0 if it is called directly, it returns 1 if it is called because longjmp is called for that setjmp.
You should think of setjmp as something that can usually be called and does nothing (returning 0) in normal operation, but returns 1, and it is indirectly called (and returns from there) when a long jump is called. I know what you mean, confusing, because it really is confusing.
This is an example provided by wikipedia:
#include <stdio.h> #include <setjmp.h> static jmp_buf buf; void second(void) { printf("second\n"); // prints longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1 } void first(void) { second(); printf("first\n"); // does not print } int main() { if ( ! setjmp(buf) ) { first(); // when executed, setjmp returns 0 } else { // when longjmp jumps back, setjmp returns 1 printf("main"); // prints } return 0; }
Can you figure it out? When the setjmp program starts, it runs in main and returns 0 (because it is called directly), so first is called, which calls second , and then it comes longjmp , which switches the context, returning to where setjmp , but this time, since it returns from the jump, and it is indirectly called the function returns 1.
A useful thing about the setjmp / longjmp approach is that you can handle error situations without having to keep the flag between function calls (especially when you have a lot, think of a recursive procedure for checking types in the compiler). If something goes wrong, as a rule, in the method of checking the call stack on the stack, you must return the flag and continue to return it to warn the caller that the typecheck check failed. With longjmp, you simply exit and handle the error without worrying about passing the flags back. The only problem is that this leads to a context switch that does not care about the standard freeing of stack / heap memory, so you have to handle it yourself.