I have a few questions relating to setjmp/longjmp usage -
What is the use of setjmp(jmp___buf stackVariables) returning 0. It is a default, which we cannot influence.
Is the only significance of setjmp(stackVariables) is to push the stack in stackVariables. And basically 0 tells us if the stack was pushed on stack_variables successfully.
Their is one occasion when the value is non-zero (any non-zero) when you return from a longjmp. What is returning from a lomgjmp, when do you return from longjmp, when your exception is handled. This is setup is really confusing.
Can some please relate it to try/throw and catch. And would be really great, if some good examples of setjmp/longjmp could be provided.
Is longJmp like throw, and it is called just after the place where exception can be raised.
Thanks.
The setjmp() function saves various information about the calling environment (typically, the stack pointer, the instruction pointer, possibly the values of other registers and the signal mask) in the buffer env for later use by longjmp(). In this case, setjmp() returns 0.
setjmp saves the current environment (the program state), at some point of program execution, into a platform-specific data structure ( jmp_buf ) that can be used at some later point of program execution by longjmp to restore the program state to that saved by setjmp into jmp_buf .
setjmp and longjmp are a pair of C function facilitating cross-procedure transfer of control. Typically they are used to allow resumption of execution at a known good point after an error. Both take as first argument a buffer, which is used to hold the machine state at the jump destination.
Exception handling is a mechanism that separates code that detects and handles exceptional circumstances from the rest of your program. Note that an exceptional circumstance is not necessarily an error. When a function detects an exceptional situation, you represent this with an object.
The C99 spec gives:
If the return is from a direct invocation, the setjmp macro returns the value zero. If the return is from a call to the longjmp function, the setjmp macro returns a nonzero value.
So the answer to 1 is that a zero indicates you have called setjmp
the first time, and non-zero indicates it is returning from a longjmp
.
It pushes the current program state. After a longjmp, the state is restored, control returns to the point it was called, and the return value is non-zero.
There are no exceptions in C. It's sort-of similar to fork
returning different values depending whether you're in the original process, or a second process which has inherited the environment, if you're familiar with that.
try
/catch
in C++ will call destructors on all automatic objects between the throw and the catch. setjmp
/longjmp
will not call destructors, as they don't exist in C. So you are on your own as far as calling free
on anything you've malloc
ed in the mean time.
With that proviso, this:
#include <stdio.h>
#include <setjmp.h>
#include <string.h>
#include <stdlib.h>
void foo ( char** data ) ;
void handle ( char* data ) ;
jmp_buf env;
int main ()
{
char* data = 0;
int res = setjmp ( env );
// stored for demo purposes.
// in portable code do not store
// the result, but test it directly.
printf ( "setjmp returned %d\n", res );
if ( res == 0 )
foo ( &data );
else
handle ( data );
return 0;
}
void foo ( char** data )
{
*data = malloc ( 32 );
printf ( "in foo\n" );
strcpy ( *data, "Hello World" );
printf ( "data = %s\n", *data );
longjmp ( env, 42 );
}
void handle ( char* data )
{
printf ( "in handler\n" );
if ( data ) {
free ( data );
printf ( "data freed\n" );
}
}
is roughly equivalent to
#include <iostream>
void foo ( ) ;
void handle ( ) ;
int main ()
{
try {
foo ();
} catch (int x) {
std::cout << "caught " << x << "\n";
handle ();
}
return 0;
}
void foo ( )
{
printf ( "in foo\n" );
std::string data = "Hello World";
std::cout << "data = " << data << "\n";
throw 42;
}
void handle ( )
{
std::cout << "in handler\n";
}
In the C case, you have to do explicit memory management (though normally you'd free it in the function which malloc'd it before calling longjmp as it makes life simpler)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With