Freigeben über


try-finally-Anweisung

Die try-finally-Anweisung ist eine Microsoft-spezifische Erweiterung, die die strukturierte Ausnahmebehandlung in den Programmiersprachen C und C++ unterstützt.

Syntax

Die folgende Syntax beschreibt die try-finally-Anweisung:

    // . . .
    __try {
        // guarded code
    }
    __finally {
        // termination code
    }
    // . . .

Grammatik

try-finally-statement:
__try compound-statement __finally compound-statement

Die try-finally-Anweisung ist eine Microsoft-Erweiterung für die Programmiersprachen C und C++, die es Zielanwendungen ermöglicht, Bereinigungscode auszuführen, wenn die Ausführung eines Codeblocks unterbrochen wird. Die Bereinigung besteht aus Aufgaben wie z. B. Neuzuweisung von Arbeitsspeicher, Schließen von Dateien und Freigeben von Dateihandles. Die try-finally-Anweisung ist besonders nützlich für Routinen, in denen an mehreren Stellen eine Fehlerüberprüfung durchgeführt wird, die eine vorzeitige Rückgabe von der Routine verursachen könnte.

Verwandte Informationen und ein Codebeispiel finden Sie unter der try-except-Anweisung. Weitere allgemeine Informationen zur strukturierten Ausnahmebehandlung finden Sie unter Strukturierte Ausnahmebehandlung. Weitere Informationen zum Behandeln von Ausnahmen in verwalteten Anwendungen mit C++/CLI finden Sie unter Ausnahmebehandlung unter /clr.

Hinweis

Die strukturierte Ausnahmebehandlung arbeitet mit Win32 für C- und C++-Quelldateien. Sie ist jedoch nicht speziell für C++ entwickelt. Sie können sicherstellen, dass der Code portabler ist, indem Sie die C++-Ausnahmebehandlung verwenden. Die C++-Ausnahmebehandlung ist auch flexibler, da sie Ausnahmen eines beliebigen Typs behandeln kann. Für C++-Programme wird empfohlen, den C++-Mechanismus zur Ausnahmebehandlung zu verwenden (try-, catch- und throw-Anweisungen).

Die Verbundanweisung nach der __try-Klausel ist der abgesicherte Abschnitt. Die Verbundanweisung nach der __finally-Klausel ist der Beendigungshandler. Der Handler gibt mehrere Aktionen an, die beim Verlassen des abgesicherten Abschnitts ausgeführt werden, ungeachtet dessen, ob der abgesicherte Abschnitt durch eine Ausnahme (ungewöhnlicher Abbruch) oder durch ein standardmäßiges Fortfahren (gewöhnlicher Abbruch) verlassen wird.

Die Steuerung erreicht eine __try-Anweisung durch einfache sequenzielle Ausführung (Fortfahren). Wenn die Steuerung zu __try wechselt, wird der zugehörige Handler aktiv. Wenn die Ablaufsteuerung das Ende des try-Blocks erreicht, wird die Ausführung wie folgt fortgesetzt:

  1. Der Beendigungshandler wird aufgerufen.

  2. Wenn der Beendigungshandler abgeschlossen ist, wird die Ausführung nach der __finally-Anweisung fortgesetzt. Wenn der abgesicherte Abschnitt beendet wird (z. B. über ein goto aus dem abgesicherten Text oder eine return-Anweisung), wird jedoch der Beendigungshandler ausgeführt, bevor die Ablaufsteuerung den abgesicherten Abschnitt verlässt.

    Eine __finally-Anweisung blockiert die Suche nach einem geeigneten Ausnahmehandler nicht.

Wenn eine Ausnahme im __try-Block auftritt, muss das Betriebssystem einen Handler für die Ausnahme finden, andernfalls tritt ein Fehler im Programm auf. Wenn ein Handler gefunden wird, werden sämtliche __finally-Blöcke ausgeführt, und die Ausführung wird im Handler fortgesetzt.

Nehmen Sie z. B. an, eine Reihe von Funktionsaufrufen verbindet Funktion A mit Funktion D, wie in der folgenden Abbildung dargestellt. Jede Funktion verfügt über einen Beendigungshandler. Wenn eine Ausnahme in Funktion D ausgelöst und in A behandelt wird, werden die Beendigungshandler in folgender Reihenfolge aufgerufen, während das System den Stapel abwickelt: D, C, B.

Abbildung der Ausführungsreihenfolge des Beendigungshandlers

Die Abbildung beginnt mit der Funktion A, die Funktion B aufruft, die Funktion C aufruft, die wiederum Funktion D aufruft. Funktion D löst eine Ausnahme aus. Die Beendigungshandler werden dann in dieser Reihenfolge aufgerufen: Beendigungshandler von D, dann von C und dann von B. A behandelt schließlich die Ausnahme.

Ausführungsreihenfolge des Beendigungshandlers

Hinweis

Das Verhalten von „try-finally“ unterscheidet sich von einigen anderen Sprachen, die die Verwendung von finally unterstützen, z. B. C#. Ein einzelnes __try hat möglicherweise entweder __finally oder __except, aber nicht beide. Wenn beide zusammen verwendet werden sollen, muss eine äußere try-except-Anweisung die innere try-finally-Anweisung einschließen. Es gelten andere Regeln für die Angabe, wann ein einzelner Block ausgeführt wird.

Für die Kompatibilität mit früheren Versionen sind _try, _finally und _leave Synonyme für __try, __finally und __leave, es sei denn, die Compileroption /Za (Spracherweiterungen deaktivieren) wird angegeben.

Das __leave-Schlüsselwort

Das Schlüsselwort __leave ist nur im geschützten Abschnitt einer try-finally-Anweisung gültig und führt zu einem Sprung zum Ende des geschützten Abschnitts. Die Ausführung wird mit der ersten Anweisung im Beendigungshandler fortgesetzt.

Eine goto-Anweisung kann auch aus dem abgesicherten Abschnitt herausspringen, jedoch wird die Leistung beeinträchtigt, da sie eine Stapelentladung aufruft. Die __leave-Anweisung ist effizienter, da sie keine Stapelentladung verursacht.

Nicht ordnungsgemäße Beendigung

Die Beendigung einer try-finally-Anweisung unter Verwendung der Runtimefunktion longjmp gilt als nicht ordnungsgemäße Beendigung. Es ist nicht zulässig, in eine __try -Anweisung zu springen, wohingegen das Herausspringen aus einer solchen zulässig ist. Alle __finally-Anweisungen, die zwischen dem Anfangspunkt (normale Beendigung des __try-Blocks) und dem Ziel (dem __except-Block, der die Ausnahme behandelt) aktiv sind, müssen ausgeführt werden. Dies wird als lokale Entladung bezeichnet.

Wenn ein __try-Block aus irgendeinem Grund vorzeitig beendet wird (auch durch Herausspringen aus dem Block), führt das System den zugehörigen __finally-Block als Teil der Entladung des Stapels aus. In solchen Fällen gibt die AbnormalTermination-Funktion true zurück, wenn sie aus dem __finally-Block aufgerufen wird. Andernfalls wird false zurückgegeben.

Der Beendigungshandler wird nicht aufgerufen, wenn ein Prozess während der Ausführung einer try-finally-Anweisung beendet wird.

ENDE der Microsoft-spezifischen Informationen

Weitere Informationen

Schreiben eines Beendigungshandlers
Structured Exception Handling (C/C++)
Schlüsselwörter
Syntax des Beendigungshandlers