Use C-stype exception handling – setjmp( ) & longjmp( )

Share the Article

Like goto call : C exception handling method, setjmp( ) and longjmp( ), is a kind of non-local goto functions in the Standard C language. Using setjmp( ) program save a known process state in a special variable of type jmp_buf. Now, if program gets into trouble, longjmp( ) will restore that state.

The difference between a local goto (to a label) and this nonlocal goto is that, the goto can jump anywhere only in a single function, but the setjmp/longjmp can enable program to go outside function boundaries.

This requires header file

#include <csetjmp>
#include <iostream> //main header #include <csetjmp> //for setjmp/longjump using namespace std; class MainFunda { public: MainFunda() { cout << "MainFunda()" << endl; } ~MainFunda() { cout << "~MainFunda()" << endl; } }; jmp_buf jmpinfo; void funda(int ix) { cout << "Start function funda()" << endl; MainFunda a1; longjmp(jmpinfo, 3); cout << "End function funda()" << endl; } int main() { int ret=setjmp(jmpinfo); if(ret==0) { cout << "Value returned by setjmp() = " << ret << endl; cout << "Start of if condition" << endl; funda(2); cout << "End of if condition" << endl; } else { cout << "Start of else condition" << endl; cout << "Value returned by longjmp() = " << ret << endl; cout << "End of else condition" << endl; } return 0; }


demonstration of set_jmp and long_jmp

How the above example works

First Return Value of setjmp: The return value from setjmp(jmpinfo) was zero. In this line, setjmp shall save the context of process internally.

int ret=setjmp(jmpinfo);

Therefore, the control goes inside “if” statement immediately after this line.

int ret=setjmp(jmpinfo); //ret = 0 if(ret==0) // control goes inside "if" {

Second Return Value of setjmp: However, when longjmp(jmpinfo, 3) executed, the control of program goes back to line where setjmp(jmpinfo) was initially executing. This happens because, now the longjmp causes the program to reload the process context which was saved earlier. However, longjmp additionally provides a different value to setjmp. Therefore, this setjmp function now returns 3. Due to non-zero return value, this time the control shall go inside “else”.

int ret=setjmp(jmpinfo); //ret = 3 if(ret==0) // control does NOT goes inside "if" {

The problem with using this method of set_jmp/long_jmp is that it do not ensure destruction of objects. The method may be good for C language exception handling, however for C++ there are problems. The use of setjmp will cause the destructors to be bypassed thus it may lead unexpected results. From the output of above example, we see that the constructor for class MainFunda was called. However, destructor is never called.

set_jmp and long_jmp do not enable call of destructor

Please Note: some C++ compilers have extended longjmp( ) to clean up objects on the stack. However, this is not standard behavior therefore, the use of longjmp in C++ may cause issues during porting.

Main Funda: c exception handling method of setjmp & longjmp is not good for C++ because they do not call destructors during clean-up

Related Topics:

Why a destructor should never throw exception?
What is the problem with setjmp( ) & longjmp( ) ?
Basics of throwing and catching exception
Why should we catch an exception object, using reference-parameter?
What happens when exception thrown from a constructor?
Re-throwing an exception
What are function level try-catch blocks
Understanding exception specification for functions
Explaining C++ casts
How pointer to class members are different ?
What is reference collapsing?
How to make a class object un-copyable?

Share the Article

Leave a Reply

Your email address will not be published. Required fields are marked *