Nach einem longjmp-Aufruf führt das C++-Laufzeitsystem für jede Funktion, die übersprungen wird, folgende Aktionen durch:
die Destruktion aller in der Funktion konstruierten und noch nicht gelöschten
automaticObjektedie Destruktion aller in der Funktion abgefangenen und noch nicht beendeten Ausnahmeobjekte
Diese Destruktionen werden allerdings nicht für die Zielfunktion des longjmp-Aufrufs selbst durchgeführt. Deshalb sollte in einer Funktion, die einen setjmp-Aufruf enthält, zwischen dem setjmp-Aufruf und dem Ansprung der Routine, die durch den longjmp abgebrochen wird, kein Objekt konstruiert, destruiert oder gefangen werden. Dies lässt sich dadurch erreichen, dass sämtlicher Code für Konstruktion, Destruktion und Auffangen von Ausnahmeobjekten in eine eigene Funktion ausgelagert wird. Damit diese Funktion nicht inline generiert wird, muss sie mittels eines externen Funktionszeigers aufgerufen werden.
Betrachten Sie hierzu das folgende Beispiel:
Beispiel
Statt der Codierung der Funktion f() in der Version 1 sollte die Codierung der Version 2 verwendet werden:
/* 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; // Keine Destruktion bei longjmp-Aufruf durch g()
g();
}
}
/* Version 2 */
void f1()
{
X x; // Destruktion bei longjmp-Aufruf durch g()
g();
}
extern void (*f1p)() = f1;
void f()
{
if (setjmp(target) == 0)
{
(*f1p)(); // f1() wird hier nicht inline generiert
}
}
longjmp und Signalroutinen
Wenn longjmp aus einer Signalroutine aufgerufen wird, werden in der Funktion, in der das Signal aufgetreten ist, keine Destruktionen für automatic Objekte und Ausnahmeobjekte durchgeführt.