After a longjmp
call, the following actions are performed by the C++ runtime system for each function that is skipped:
All
automatic
objects that were constructed in the function but not deleted are destroyed.All exception objects which were caught in the function but which have not terminated are destroyed.
Note, however, that these destructors are not invoked for the target function of the longjmp
call itself. Consequently, in a function containing a setjmp
call, no object should be constructed, destroyed or caught between the setjmp
call and the entry of the routine aborted by the longjmp
. This can be achieved by relocating all code for constructors, destructors and catching exceptions to a separate function. Furthermore, in order to prevent this function from being inlined, it must be called via an external function pointer. Consider the following example:
Example
Instead of using the code of the function f()
in Version 1, the code of Version 2 is to be used:
/* Version 1 */
#include <setjmp> jmp_buf target; void g(); class X { ~X(); }; void g() { longjmp(target, 1); } void f() { if (setjmp(target) == 0) { X x; // No destruction for longjmp call by g() g(); } }
/* Version 2 */
void f1() { X x; // Destruction for longjmp call by g() g(); } extern void (*f1p)() = f1; void f() { if (setjmp(target) == 0) { (*f1p)(); // f1() is not inlined here } }
longjmp and signal routines
When longjmp
is called from a signal routine, no destructors for automatic
and exception objects are executed in the function in which the signal occurred.