Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

longjmp - Nicht lokaler Sprung

&pagelevel(4)&pagelevel

Definition

#include <setjmp.h>

void longjmp(jmp_buf env, int wert);

longjmp ist nur zusammen mit der Funktion setjmp anwendbar: Der Aufruf von longjmp bewirkt, dass das Programm an eine zuvor mit setjmp „gemerkte“ Stelle verzweigt. Im Unterschied zu goto-Sprüngen, die nur innerhalb derselben Funktion (also lokal) zulässig sind, erlauben longjmp und setjmp Sprünge von einer beliebigen Funktion in eine andere, noch aktive Funktion (nicht lokale Sprünge).

setjmp speichert den aktuellen Programmzustand (Adresse im C-Laufzeitstack, Befehlszähler, Registerinhalte) in eine Variable vom Typ jmp_buf (definiert in <setjmp.h>). longjmp stellt den durch setjmp gesicherten Programmzustand wieder her, und das Programm wird mit der Anweisung fortgesetzt, die unmittelbar auf den setjmp-Aufruf folgt.

Parameter

jmp_buf env

Feld, in das setjmp seine Werte abgelegt hat. Der Typ jmp_buf ist in <setjmp.h> definiert.

int wert

Ganze Zahl, die beim Wiederaufsetzen der Programmausführung als Rückgabewert des setjmp-Aufrufs interpretiert wird. Falls wert gleich 0 ist, liefert setjmp den Wert 1 zurück; 0 würde bedeuten, dass an die Stelle nach dem setjmp-Aufruf „normal“, d.h. nicht mit longjmp verzweigt wurde (siehe auch setjmp).

Hinweise

Das Verhalten ist undefiniert, wenn longjmp mit einem Argument env aufgerufen wird, das nicht zuvor durch einen setjmp-Aufruf belegt wurde.

Die Funktion, die den setjmp-Aufruf mit der Variablen env enthält, muss beim longjmp-Ansprung mit derselben Variablen noch aktiv sein, d.h. sie darf inzwischen nicht beendet worden sein (z.B. mit exit oder return).

Nicht lokale Sprünge sind nützlich bei der Unterbrechungsbehandlung (siehe signal). Erfolgt z.B. die Behandlung von Fehlern oder Unterbrechungen in Routinen auf niedriger Stufe (d.h. es sind eine Reihe zuvor aufgerufener Funktionen noch aktiv), lässt sich mit longjmp und setjmp die normale Abarbeitung der noch aktiven Funktionen umgehen und sofort zu einer Funktion auf höherer Ebene verzweigen. Ein longjmp-Aufruf aus einer Unterbrechungs oder Fehlerroutine leert die Einträge im Laufzeitstack bis zu der durch setjmp markierten Stelle, d.h. alle bis dahin noch aktiven Funktionen auf niedrigerer Ebene sind nicht mehr aktiv und das Programm wird auf höherer Ebene fortgesetzt.

Beim Wiederaufsetzen der Programmausführung sind die Variablen wie nach einem goto belegt: Globale Variablen haben die Werte, die sie zum Zeitpunkt des longjmp-Aufrufs hatten. Register- und sonstige lokale Variablen sind undefiniert, d.h. sie sollten überprüft und ggf. neu belegt werden.

Beispiel

Ein typischer Anwendungsfall für setjmp und longjmp ist die Text-Ein-/Ausgabe in einem interaktiven Texteditor.
Wird während der Ein- bzw. Ausgabe das Programm unterbrochen, indem von außen ein Signal geschickt wird (z.B. Drücken der K2-Taste nach „please acknowledge“ oder nach einer Eingabeaufforderung), bewirkt dies das Ende der Text-Ein-/Ausgabe, ansonsten fährt der Texteditor mit der Ein-/Ausgabe fort.
Wie das mit setjmp und longjmp realisiert werden kann, sehen Sie in folgendem Programm (nur Signalbehandlung, kein Editor!):

#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
FILE *fp;
jmp_buf env;
void intr(int sig)
{
   printf("\n   ***** Sie wollen den Text nicht? ****** \n");
   longjmp(env,0);
}
int main(void)
{  int c; char reply;
   setjmp(env);
   signal(SIGINT,intr);
   printf("Textausgabe? (y?n):\n");
   scanf("%1s",&reply);              /* Unterbrechung mit K2 möglich */
   if(reply == 'y')
     {
      fp = fopen("text","r");        /* Datei text muss existieren */
      while((c=getc(fp)) != EOF)
            putc((char)c,stdout);    /* Unterbrechung der Textausgabe mit K2
                                        nach "please acknowledge" möglich */
     }
   else printf("Keine Textausgabe\n");
   return 0;  }

Siehe auch

setjmp, signal