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 NummerVariablen & Beschreibung
1jmp_buf

jmp_bufist ein Datentyp, der zum Speichern der Aufrufumgebung verwendet wird, einschließlich Stackzeiger, Instruktionszeiger, Register usw. Beim Ausführensetjmp()wenn, dann werden diese Umgebungsinformationen gespeichert injmp_bufin Variablen des Typs.

Bibliotheksmakros

Das Folgende ist das einzige in dieser Bibliothek definierte Makro:

Laufende NummerMakros & Beschreibung
1int 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 NummerFunktionen & Beschreibung
1void 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 <stdio.h>
#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 Funktionsaufrufensetjmp()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

  • Nutzungsetjmp()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 vermeidensetjmp()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.

Weitere Erweiterungen