setjmp is used to place a marker to where the call of longjump should return, it returns 0 if it is called directly, it returns 1 if it's called because a longjmp to that setjmp is invoked.
You have to think about setjmp like something that can be normally called and does not do anything (returning 0) in normal operation while returns 1 and it's indirectly called (and returns from there) when a long jump is called. I know what you mean about confusing because it's actually confusing..
This is the example given 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;
}
Are you able to understand it?
When program is launched setjmp
is executed in main and returns 0 (because it is directly called), so first
is called, that calls second
and then it arrives longjmp
that switches context going back to where setjmp
was used, but this time, since it goes back from a jump and it is indirectly called the function returns 1.
The useful thing of setjmp/longjmp approach is that you can handle error situations without caring to keep a flag between function calls (especially when you have many, think about a recursive procedure for typechecking in a compiler). If something goes wrong in typechecking deep in call stack normally you have to return a flag and keep returning it to warn the caller that typechecking failed. With longjmp you just go out and handle error without caring about passing flags back. The only problem is that this forces a context switch that doesn't care about standard deallocation of stack/heap memory so you should handle it by yourself.