Structured Exception Handling (C/C++)
Die strukturierte Ausnahmebehandlung (SEH) ist eine Microsoft-Erweiterung für C und C++ zur Behandlung bestimmter außergewöhnlicher Codesituationen, z. B. Hardwarefehler, ordnungsgemäß. Obwohl Windows und Microsoft C++ SEH unterstützen, empfehlen wir, die C++-Ausnahmebehandlung im C++-Code nach ISO-Standard zu verwenden. Es macht Ihren Code portierbarer und flexibler. Um jedoch vorhandenen Code oder für bestimmte Arten von Programmen zu Standard, müssen Sie möglicherweise weiterhin SEH verwenden.
Microsoft-spezifisch:
Grammatik
try-except-statement
:
__try
compound-statement
__except
(
filter-expression
)
compound-statement
try-finally-statement
:
__try
compound-statement
__finally
compound-statement
Hinweise
Mit SEH können Sie sicherstellen, dass Ressourcen, z. B. 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 angewiesen ist, oder aufwendige Tests von Rückgabecodes.
Die try-except
in diesem Artikel genannten Anweisungen und try-finally
Anweisungen sind Microsoft-Erweiterungen für die Sprachen C und 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 mithilfe der /EHa
Oder-Option /EHsc
kompilieren, werden Destruktoren für lokale Objekte aufgerufen, andere Ausführungsverhalten sind jedoch möglicherweise nicht das, was Sie erwarten. Eine Abbildung finden Sie im Beispiel weiter unten in diesem Artikel. In den meisten Fällen wird anstelle von SEH empfohlen, die ISO-Standard-C ++-Ausnahmebehandlung zu verwenden. 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 C++-Ausnahmebehandlung verwendet. Weitere Informationen finden Sie unter Behandeln strukturierter Ausnahmen in C++.
Es gibt zwei SEH-Mechanismen:
Ausnahmehandler oder
__except
Blöcke, die auf die Ausnahme basierend auf demfilter-expression
Wert reagieren oder schließen können. Weitere Informationen finden Sie intry-except
der Anweisung.Beendigungshandler oder
__finally
Blöcke, die immer aufgerufen werden, unabhängig davon, ob eine Ausnahme eine Beendigung verursacht oder nicht. Weitere Informationen finden Sie intry-finally
der Anweisung.
Diese beiden Arten von Handlern sind unterschiedlich, aber eng miteinander verbunden durch einen Prozess, der als Entspannen des Stapels bezeichnet 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 Übergeben des Steuerelements an andere Handler (
EXCEPTION_CONTINUE_SEARCH
).Erkennen Sie die Ausnahme, schließen Sie sie aber (
EXCEPTION_CONTINUE_EXECUTION
).Erkennen Sie die Ausnahme, und behandeln Sie sie (
EXCEPTION_EXECUTE_HANDLER
).
Der Ausnahmehandler, der die Ausnahme erkennt, befindet sich möglicherweise nicht in der Funktion, die bei Auftreten der Ausnahme ausgeführt wurde. Es kann sich in einer Funktion viel höher auf dem Stapel befinden. Die gegenwärtig ausgeführte Funktion sowie alle weiteren Funktionen im Stapelrahmen werden beendet. Während dieses Vorgangs wird der Stapel entwunden. 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. Durch die Verwendung eines Beendigungshandlers sauber Sie Ressourcen auf, die andernfalls aufgrund einer ungewöhnlichen Beendigung wieder geöffnet würden Standard. Wenn Sie einen kritischen Abschnitt eingegeben haben, können Sie ihn im Beendigungshandler beenden. Wenn das Programm heruntergefahren wird, können Sie andere Hausaufgaben 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 mithilfe der /EHa
Option /EHsc
kompilieren. 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!\n");
}
};
__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
printf("Throwing C++ exception\n");
throw std::exception("");
#else
printf("Triggering SEH exception\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\n");
}
return 0;
}
Wenn Sie /EHsc
diesen Code 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
den Code kompilieren und CPPEX
mithilfe /DCPPEX
von Code definiert werden (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
den Code kompilieren, wird vom TestClass
Destruktor ausgeführt, ob eine Ausnahme mit einem C++ throw
-Standardausdruck oder mit SEH ausgelöst 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 /EH
(Ausnahmebehandlungsmodell).
ENDE der Microsoft-spezifischen Informationen
Siehe auch
Ausnahmenbehandlung
Schlüsselwörter
<exception>
Fehler- und Ausnahmebehandlung
Strukturierte Ausnahmebehandlung (Windows)
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für