Structured Exception Handling (C/C++)

Die strukturierte Ausnahmebehandlung (Structured Exception Handling, SEH) ist eine Microsoft-Erweiterung für C, um bestimmte ausnahmehafte Codesituationen wie Hardwarefehler ordnungsgemäß zu behandeln. Obwohl Windows und Microsoft C++ SEH unterstützen, wird empfohlen, die C++-Ausnahmebehandlung nach ISO-Standard zu verwenden. Dadurch wird Ihr Code portierbarer und flexibler. Um jedoch vorhandenen Code oder für bestimmte Arten von Programmen zu verwalten, müssen Sie möglicherweise weiterhin SEH verwenden.

Microsoft-spezifisch:

Grammatik

try-except-statement :
__try compound-statement __except ( expression ) compound-statement

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

Bemerkungen

Mit SEH können Sie sicherstellen, dass Ressourcen wie Speicherblöcke und Dateien ordnungsgemäß freigegeben werden, wenn die Ausführung unerwartet beendet wird. Sie können auch bestimmte Probleme — behandeln, z. B. unzureichenden Arbeitsspeicher, indem Sie — präzisen strukturierten Code verwenden, der nicht auf goto Anweisungen oder aufwendigen Tests von Rückgabecodes beruht.

Die try-except anweisungen und , auf die in diesem Artikel verwiesen try-finally wird, sind Microsoft-Erweiterungen der Programmiersprache C. Sie unterstützen SEH, indem es Anwendungen ermöglicht wird, die Steuerung eines Programms nach Ereignissen abzurufen, die andernfalls das Beenden der Ausführung zur Folge haben würden. Obwohl SEH mit C++-Quelldateien funktioniert, ist sie nicht ausdrücklich für C++ vorgesehen. Wenn Sie SEH in einem C++-Programm verwenden, das Sie mit der Option oder /EHsc kompilieren, werden Destruktoren für lokale Objekte aufgerufen, aber ein anderes Ausführungsverhalten ist möglicherweise nicht das erwartete Verhalten. Eine Abbildung finden Sie im Beispiel weiter unten in diesem Artikel. In den meisten Fällen wird anstelle von SEH empfohlen, die C++-Ausnahmebehandlungnach ISO-Standard zu verwenden, die auch vom Microsoft C++-Compiler unterstützt wird. Mithilfe der C++-Ausnahmebehandlung können Sie eine bessere Portierbarkeit des Codes sicherstellen, und Sie können Ausnahmen jeglichen Typs behandeln.

Wenn Sie über C-Code verfügen, der SEH verwendet, können Sie ihn mit C++-Code kombinieren, der die C++-Ausnahmebehandlung verwendet. Weitere Informationen finden Sie unter Behandeln strukturierter Ausnahmen in C++.

Es gibt zwei SEH-Mechanismen:

  • Ausnahmehandleroder -Blöcke, die auf die Ausnahme reagieren oder diese schließen können.

  • Beendigungshandleroder -Blöcke, die immer aufgerufen werden, unabhängig davon, ob eine Ausnahme eine Beendigung verursacht oder nicht.

Diese beiden Arten von Handlern unterscheiden sich, sind jedoch eng mit einem Prozess verknüpft, der als Entladung des Stapelsbezeichnet wird. Wenn eine strukturierte Ausnahme auftritt, sucht Windows nach dem zuletzt installierten Ausnahmehandler, der derzeit aktiv ist. Beim Handler kann eine von drei Möglichkeiten auftreten:

  • Fehler beim Erkennen der Ausnahme und Übergabe des Steuerelements an andere Handler

  • Erkennen der Ausnahme, diese aber zurückweisen

  • Erkennen und behandeln der Ausnahme

Der Ausnahmehandler, der die Ausnahme erkennt, befindet sich möglicherweise nicht in der Funktion, die bei Auftreten der Ausnahme ausgeführt wurde. Sie kann sich in einer Funktion befinden, die viel höher im Stapel ist. Die gegenwärtig ausgeführte Funktion sowie alle weiteren Funktionen im Stapelrahmen werden beendet. Während dieses Prozesses wird der Stapel entladen. Das heißt, lokale nicht statische Variablen von beendeten Funktionen werden aus dem Stapel gelöscht.

Beim Entladen des Stapels ruft das Betriebssystem alle Beendigungshandler auf, die Sie für jede Funktion geschrieben haben. Mithilfe eines Beendigungshandlers bereinigen Sie Ressourcen, die andernfalls aufgrund einer ungewöhnlichen Beendigung geöffnet bleiben würden. Wenn Sie einen kritischen Abschnitt eingegeben haben, können Sie ihn im Beendigungshandler beenden. Wenn das Programm heruntergefahren wird, können Sie andere Housekeeping-Aufgaben ausführen, z. B. das Schließen und Entfernen temporärer Dateien.

Nächste Schritte

Beispiel

Wie bereits erwähnt, werden Destruktoren für lokale Objekte aufgerufen, wenn Sie SEH in einem C++-Programm verwenden und es mit der /EHa Option oder kompilieren. /EHsc Das Verhalten während der Ausführung ist jedoch möglicherweise nicht das, was Sie erwarten, wenn Sie auch C++-Ausnahmen verwenden. In diesem Beispiel werden diese Verhaltensunterschiede veranschaulicht.

#include <stdio.h>
#include <Windows.h>
#include <exception>

class TestClass
{
public:
    ~TestClass()
    {
        printf("Destroying TestClass!\r\n");
    }
};

__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
    printf("Throwing C++ exception\r\n");
    throw std::exception("");
#else
    printf("Triggering SEH exception\r\n");
    volatile int *pInt = 0x00000000;
    *pInt = 20;
#endif
}

__declspec(noinline) void TestExceptions()
{
    TestClass d;
    TestCPPEX();
}

int main()
{
    __try
    {
        TestExceptions();
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        printf("Executing SEH __except block\r\n");
    }

    return 0;
}

Wenn Sie /EHsc verwenden, um diesen Code zu kompilieren, aber das lokale Teststeuerelementmakro CPPEX nicht definiert ist, wird der TestClass Destruktor nicht ausgeführt. Die Ausgabe sieht wie folgt aus:

Triggering SEH exception
Executing SEH __except block

Wenn Sie /EHsc zum Kompilieren des Codes verwenden und CPPEX mithilfe von definiert wird /DCPPEX (sodass eine C++-Ausnahme ausgelöst wird), wird der TestClass Destruktor ausgeführt, und die Ausgabe sieht wie folgt aus:

Throwing C++ exception
Destroying TestClass!
Executing SEH __except block

Wenn Sie /EHa verwenden, um den Code zu kompilieren, führt der TestClass Destruktor aus, ob eine Ausnahme mithilfe eines C++-Standardausdrucks oder mit SEH ausgelöst throw wurde. Das heißt, ob CPPEX definiert ist oder nicht. Die Ausgabe sieht wie folgt aus:

Throwing C++ exception
Destroying TestClass!
Executing SEH __except block

Weitere Informationen finden Sie unter (Ausnahmebehandlungsmodell).

ENDE der Microsoft-spezifischen Informationen

Siehe auch

Ausnahmebehandlung
Schlüsselwörter
<exception>
Fehler und Ausnahmebehandlung
Strukturierte Ausnahmebehandlung (Windows)