C-Standardbibliothek -<setjmp.h>
Einführung
setjmp.hDie Headerdatei definiert Makrossetjmp(), Funktionlongjmp()und Variablentypenjmp_buf, dieser Variablentyp umgeht die normalen Funktionsaufruf- und Rückgaberegeln.
<setjmp.h>ist eine Headerdatei in der C-Standardbibliothek, die eine Reihe von Funktionen und Makros für nichtlokale Sprünge bereitstellt (d. h. das Springen von einer Funktion zu einer anderen Funktion, die zuvor aufgerufen wurde, ohne den normalen Mechanismus der Funktionsrückgabe zu erfordern). Dieser Mechanismus wird üblicherweise zur Fehlerbehandlung, Ausnahmebehandlung oder zum Verlassen tief verschachtelter Schleifen oder Rekursionen verwendet.
Bibliotheksvariablen
Im Folgenden werden die in der Headerdatei setjmp.h definierten Variablen aufgelistet:
| Laufende Nummer | Variablen & Beschreibung |
|---|---|
| 1 | jmp_buf
|
Bibliotheksmakros
Das Folgende ist das einzige in dieser Bibliothek definierte Makro:
| Laufende Nummer | Makros & Beschreibung |
|---|---|
| 1 | int setjmp(jmp_buf environment) Dieses Makro speichert die aktuelle Umgebung in der Variablenenvironment, damit Funktionenlongjmp()später verwenden können. Wenn dieses Makro direkt von einem Makroaufruf zurückkehrt, gibt es null zurück, aber wenn es von einemlongjmp()Funktionsaufruf zurückkehrt, gibt es einen Wert ungleich null zurück. |
Bibliotheksfunktionen
Das Folgende ist die einzige Funktion, die in der Header-Datei setjmp.h definiert ist:
| Laufende Nummer | Funktionen & Beschreibung |
|---|---|
| 1 | void longjmp(jmp_buf environment, int value) Diese Funktion stellt die Umgebung wieder her, die beim letzten Aufruf vonsetjmp()gespeichert wurde, als das Makro aufgerufen wurde.jmp_bufDie Parametereinstellung wird durch einen vorherigen Aufruf von setjmp() erzeugt. |
Beispiel
Das folgende Beispiel zeigt, wie man setjmp() und longjmp() verwendet, um nicht-lokale Sprünge zu implementieren:
Beispiel
#include <setjmp.h>
jmp_buf env;
void second() {
printf("Entering second()\n");
longjmp(env, 1);
printf("This line will never be executed\n");
}
void first() {
printf("Eintritt in first()\n");
if (setjmp(env) == 0) {
printf("Aufruf von second() aus first()\n");
second();
} else {
printf("Zurückgekehrt zu first() von second() mittels longjmp\n");
}
printf("Verlassen von first()\n");
}
int main() {
printf("Start von main()\n");
first();
printf("Verlassen von main()\n");
return 0;
}
Das Ausführen des obigen Programms gibt ungefähr Folgendes aus:
Starting main() Entering first() Calling second() from first() Entering second() Returned to first() from second() using longjmp Exiting first() Exiting main()
Code-Erklärung
jmp_buf env: eine Variable zum Speichern von Umgebungsinformationen definierenenv。first()Funktion: Aufrufsetjmp(env)die aktuellen Umgebungsinformationen speichern und anhand ihres Rückgabewerts entscheiden, ob aufgerufen werden sollsecond()Funktion.second()Funktion: Aufruflongjmp(env, 1), springe zurück zusetjmp(env), und dafür sorgen, dass es 1 zurückgibt.main()Funktion: Aufruffirst()Funktion.
Anwendungsfall
- Fehlerbehandlung: verwendet bei tief verschachtelten Funktionsaufrufen
setjmp()undlongjmp()um einen Fehlerbehandlungsmechanismus zu implementieren. - Ausnahmebehandlung: verwendet, um eine einfache Ausnahmebehandlung zu implementieren.
- den Kontrollfluss unterbrechen: In bestimmten Fällen kann der normale Kontrollfluss unterbrochen werden, um aus mehreren Ebenen verschachtelter Schleifen oder Funktionsaufrufe auszubrechen.
Hinweise
- Nutzung
setjmp()undlongjmp()Man muss vorsichtig sein, denn sie überspringen den normalen Stack-Abwicklungsprozess, was zu Ressourcenlecks führen kann (z. B. nicht freigegebener Speicher, nicht geschlossene Dateien usw.). - beim Aufrufen vermeiden
setjmp()undlongjmp()zwischen dem Ändern lokaler Variablen, weil dies zu undefiniertem Verhalten führen kann. - Nicht-lokale Sprünge können den Code schwer lesbar und schwer zu debuggen machen, daher sollten sie mit Vorsicht verwendet werden.
Zusammenfassung
<setjmp.h>bietetsetjmp()undlongjmp()Funktionen, die zur Implementierung nicht-lokaler Sprünge verwendet werden. Diese Funktionen sind bei der Fehler- und Ausnahmebehandlung sehr nützlich, müssen aber mit Vorsicht verwendet werden, um potenzielle Probleme zu vermeiden.