c / expert
Snippet
Nicht-lokale Sprünge mit setjmp und longjmp
Nicht-lokale Sprünge ermöglichen es dem Steuerfluss, standardmäßige Funktionsaufrufe und Rücksprünge über den Aufruf-Stack hinweg zu umgehen. Der Aufruf von `setjmp` speichert den aktuellen Ausführungszustand (Register und Stack-Kontext) in einer `jmp_buf`-Struktur und gibt zunächst 0 zurück. Ein späterer Aufruf von `longjmp` stellt diesen gespeicherten Zustand wieder her, sodass `setjmp` ein zweites Mal zurückzukehren scheint – mit dem an `longjmp` übergebenen Nicht-Null-Wert. Dieses Muster simuliert Exception-Handling-Mechanismen in der C-Systemprogrammierung.
snippet.c
c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>#include <setjmp.h>static jmp_buf env;void error_recovery(int code) {printf("Error caught: %d. Unwinding execution stack...\n", code);longjmp(env, code);}void process_data(int value) {if (value < 0) {error_recovery(101);}printf("Processing valid value: %d\n", value);}int main(void) {int status = setjmp(env);if (status == 0) {process_data(42);process_data(-5);} else {printf("Execution restored at main. Error code: %d\n", status);}return 0;}
Erklärung
1
static jmp_buf env;
Allokiert Pufferspeicher zum Speichern des Prozessor-Kontexts und der Stack-Umgebung.
2
int status = setjmp(env);
Speichert den Ausführungszustand in env; gibt 0 beim Erstaufruf zurück und einen Wert ungleich 0 bei der Wiederherstellung durch longjmp.
3
longjmp(env, code);
Stellt den in env gespeicherten Prozessorzustand wieder her und springt direkt zur setjmp-Aufrufstelle zurück.