/EH
(Ausnahmebehandlungsmodell)
Gibt die vom Compiler generierte Unterstützung des Ausnahmebehandlungsmodells an. Argumente geben an, ob syntax sowohl auf strukturierte als auch auf Standard-C++-Ausnahmen angewendet werden sollcatch(...)
, obextern "C"-Code für throw Ausnahmen angenommen wird und ob bestimmte noexcept
Prüfungen entfernt werden sollen.
Syntax
/EHa
[-
]
/EHs
[-
]
/EHc
[-
]
/EHr
[-
]
Argumente
a
Ermöglicht das Abwickeln von C++-Standardstapeln. Erfasst sowohl strukturierte (asynchrone) als auch standardmäßige C++-Ausnahmen (synchron), wenn Sie syntax verwenden catch(...)
. /EHa
überschreibt sowohl als auch /EHs
/EHc
Argumente.
s
Ermöglicht das Abwickeln von C++-Standardstapeln. Erfasst nur Standard-C++-Ausnahmen, wenn Sie Syntax verwenden catch(...)
. Sofern nicht /EHc
auch angegeben, geht der Compiler davon aus, dass als "C" deklarierte extern Funktionen eine C++-Ausnahme darstellen könnenthrow.
c
Bei Verwendung mit /EHs
dem Compiler wird davon ausgegangen, dass funktionen, die als extern "C" deklariert wurden, niemals throw eine C++-Ausnahme. Sie hat keine Wirkung, wenn sie verwendet /EHa
wird (d /EHca
. d. s. entspricht /EHa
). /EHc
wird ignoriert, wenn /EHs
oder /EHa
nicht angegeben wird.
r
Weist den Compiler an, immer Laufzeitbeendigungsprüfungen für alle noexcept
-Funktionen zu generieren. Standardmäßig können Laufzeitprüfungen für noexcept
wegoptimiert werden, wenn der Compiler feststellt, dass die Funktion nur nicht auslösende Funktionen aufruft. Diese Option bietet eine strenge C++-Konformität zu Kosten eines zusätzlichen Codes. /EHr
wird ignoriert, wenn /EHs
oder /EHa
nicht angegeben wird.
-
Löscht das vorherige Optionsargument. Beispielsweise /EHsc-
wird als /EHs /EHc-
, und entspricht dem ./EHs
/EH
Argumente können separat oder kombiniert in beliebiger Reihenfolge angegeben werden. Wenn mehr als eine Instanz desselben Arguments angegeben ist, überschreibt die letzte Instanz frühere Argumente. Ist z. B /EHr- /EHc /EHs
. identisch mit /EHscr-
, und /EHscr- /EHr
hat die gleiche Wirkung wie /EHscr
.
Hinweise
Standardverhalten für die Ausnahmebehandlung
Der Compiler generiert immer Code, der die asynchrone strukturierte Ausnahmebehandlung (SEH) unterstützt. Standardmäßig (d. h. wenn keine /EHsc
, /EHs
oder /EHa
Option angegeben ist), unterstützt SEH der Compiler Handler in der systemeigenen C++ catch(...)
-Klausel. Es generiert jedoch auch Code, der nur teilweise C++-Ausnahmen unterstützt. Die Standardausnahme beim Abwickeln von Code zerstört keine automatischen C++-Objekte außerhalb von try
Blöcken, die aufgrund einer Ausnahme außerhalb des Gültigkeitsbereichs verlaufen. Ressourcenlecks und nicht definiertes Verhalten können dazu führen, dass eine C++-Ausnahme ausgelöst wird.
Standard-C++-Ausnahmebehandlung
Vollständige Compilerunterstützung für das Standard-C++-Ausnahmebehandlungsmodell, das Stapelobjekte /EHsc
sicher entspannt (empfohlen), /EHs
oder /EHa
.
Wenn Sie die Klauseln verwenden /EHs
oder/EHsc
catch(...)
, werden keine catch asynchronen strukturierten Ausnahmen verwendet. Alle Zugriffsverletzungen und verwalteten System.Exception Ausnahmen gehen unangetastet. Und Objekte im Bereich, wenn eine asynchrone Ausnahme auftritt, werden nicht zerstört, auch wenn der Code die asynchrone Ausnahme behandelt. Dieses Verhalten ist ein Argument, um strukturierte Ausnahmen nicht behandelt zu lassen. Betrachten Sie stattdessen diese Ausnahmen als schwerwiegend.
Bei Verwendung /EHs
oder /EHsc
, geht der Compiler davon aus, dass Ausnahmen nur bei einer throw
Anweisung oder bei einem Funktionsaufruf auftreten können. Diese Annahme ermöglicht es dem Compiler, Code zum Nachverfolgen der Lebensdauer vieler abwickelbarer Objekte zu beseitigen, wodurch die Codegröße erheblich reduziert werden kann. Wenn Sie das ausführbare Image verwenden /EHa
, ist das ausführbare Image möglicherweise größer und langsamer, da der Compiler Blöcke nicht so aggressiv optimiert try
. Sie enthält auch Ausnahmefilter, die lokale Objekte automatisch bereinigen, auch wenn der Compiler keinen Code sieht, der eine C++-Ausnahme haben kann throw .
Strukturierte und standardmäßige C++-Ausnahmebehandlung
Die /EHa
Compileroption ermöglicht das Abwickeln sicherer Stapel sowohl für asynchrone Ausnahmen als auch für C++-Ausnahmen. Sie unterstützt die Behandlung von standardmäßigen C++- und strukturierten Ausnahmen mithilfe der systemeigenen C++ catch(...)
-Klausel. Um ohne Angabe zu implementierenSEH, können Sie die Syntax und __finally
die __try
Syntax __except
verwenden./EHa
Weitere Informationen finden Sie unter Strukturierte Ausnahmebehandlung.
Wichtig
Das Angeben /EHa
und Versuchen, alle Ausnahmen mithilfe von catch(...)
Ausnahmen zu behandeln, kann gefährlich sein. Da asynchrone Ausnahmen größtenteils nicht behebbar sind, gelten sie als schwerwiegende Ausnahmen. Wenn Sie sie abfangen und den Prozess anschließend fortsetzen, können Beschädigungen und Fehler auftreten, die schwer zu finden und zu beheben sind.
Obwohl Windows und Visual C++-Unterstützung unterstützt SEHwerden, empfehlen wir dringend, dass Sie die ISO-Standard-C++-Ausnahmebehandlung (/EHsc
oder /EHs
) verwenden. Dadurch wird Ihr Code besser portierbar und flexibler. Es kann immer noch vorkommen, dass Sie in Legacycode oder für bestimmte Arten von Programmen verwenden SEH müssen. Sie ist in Code erforderlich, der kompiliert wird, um beispielsweise die Common Language Runtime (/clr
) zu unterstützen. Weitere Informationen finden Sie unter Strukturierte Ausnahmebehandlung.
Es wird empfohlen, niemals Objektdateien zu verknüpfen, die mit /EHa
denen kompiliert wurden, die mit /EHs
oder /EHsc
im selben ausführbaren Modul kompiliert wurden. Wenn Sie eine asynchrone Ausnahme mithilfe /EHa
einer beliebigen Stelle in Ihrem Modul behandeln müssen, müssen Sie /EHa
den gesamten Code im Modul kompilieren. Sie können die Syntax für die strukturierte Ausnahmebehandlung im selben Modul wie Code verwenden, der mithilfe von /EHs
. Sie können die SEH Syntax jedoch nicht mit C++ try
und throw
catch
in derselben Funktion kombinieren.
Verwenden Sie /EHa
diesen Wert, wenn Sie eine Ausnahme verwenden catch möchten, die von einer anderen Ausnahme als einer throw
ausgelöst wird. Im nachfolgenden Beispiel wird eine strukturierte Ausnahme generiert und abgefangen:
// compiler_options_EHA.cpp
// compile with: /EHa
#include <iostream>
#include <excpt.h>
using namespace std;
void fail()
{
// generates SE and attempts to catch it using catch(...)
try
{
int i = 0, j = 1;
j /= i; // This will throw a SE (divide by zero).
printf("%d", j);
}
catch(...)
{
// catch block will only be executed under /EHa
cout << "Caught an exception in catch(...)." << endl;
}
}
int main()
{
__try
{
fail();
}
// __except will only catch an exception here
__except(EXCEPTION_EXECUTE_HANDLER)
{
// if the exception was not caught by the catch(...) inside fail()
cout << "An exception was caught in __except." << endl;
}
}
Ausnahmebehandlung unter /clr
Die /clr
Option impliziert /EHa
(d. s /clr /EHa
. ist redundant). Der Compiler generiert einen Fehler, wenn /EHs
er nach /clr
./EHsc
Optimierungen wirken sich nicht auf dieses Verhalten aus. Wenn eine Ausnahme abgefangen wird, ruft der Compiler die Klassendestruktoren für alle Objekte auf, die sich im selben Bereich wie die Ausnahme befinden. Wenn eine Ausnahme nicht abgefangen wird, werden diese Destruktoren nicht ausgeführt.
Informationen zu Ausnahmebehandlungseinschränkungen finden Sie unter /clr
_set_se_translator.
Laufzeit-Ausnahmeprüfungen
Die /EHr
Option erzwingt laufzeitende Prüfungen in allen Funktionen, die über ein noexcept
Attribut verfügen. Standardmäßig können Laufzeitüberprüfungen entfernt werden, wenn das Compiler-Back-End feststellt, dass eine Funktion nur nicht ausgelöste Funktionen aufruft. Nicht auslösende Funktionen sind alle Funktionen, die ein Attribut haben, das angibt, dass keine Ausnahmen ausgelöst werden können. Sie enthalten Funktionen, die markiert sindnoexcept
, throw()
__declspec(nothrow)
und, wenn /EHc
angegeben, extern "C"
Funktionen. Zu den nicht auslösenden Funktionen gehört auch jede Funktion, für die der Compiler durch Prüfung ermittelt hat, dass sie nicht auslösend ist. Sie können das Standardverhalten explizit mithilfe von /EHr-
.
Ein nicht ausgelöstes Attribut ist keine Garantie dafür, dass Ausnahmen nicht von einer Funktion ausgelöst werden können. Im Gegensatz zum Verhalten einer noexcept
Funktion betrachtet der MSVC-Compiler eine Ausnahme, die von einer funktion ausgelöst wird, die mit throw()
, __declspec(nothrow)
oder extern "C"
als nicht definiertes Verhalten deklariert wurde. Funktionen, die diese drei Deklarationsattribute verwenden, erzwingen keine Laufzeitendpunktüberprüfungen auf Ausnahmen. Sie können die /EHr
Option verwenden, um dieses nicht definierte Verhalten zu identifizieren, indem Sie den Compiler zwingen, Laufzeitprüfungen auf unbehandelte Ausnahmen zu generieren, die einer noexcept
Funktion entweichen.
Festlegen der Option in Visual Studio oder programmgesteuert
So legen Sie diese Compileroption in der Visual Studio-Entwicklungsumgebung fest
Öffnen Sie das Dialogfeld Eigenschaftenseiten des Projekts. Weitere Informationen erhalten Sie unter Set C++ compiler and build properties in Visual Studio (Festlegen der Compiler- und Buildeigenschaften (C++) in Visual Studio).
Wählen Sie konfigurationseigenschaften>C/C++>-Codegenerierung aus.
Ändern Sie die Eigenschaft C++-Ausnahmen aktivieren .
Oder legen Sie den Wert für C++-Ausnahmen aktivieren auf Neinfest, und fügen Sie dann auf der Eigenschaftenseite Befehlszeile im Feld Zusätzliche Optionen die Compileroption hinzu.
So legen Sie diese Compileroption programmgesteuert fest
- Siehe ExceptionHandling.
Siehe auch
MSVC-Compileroptionen
MSVC Compiler-Befehlszeilensyntax
Modernes C++: Best Practices für Ausnahmen und Fehlerbehandlung
Ausnahmespezifikationen (throw)
Structured Exception Handling (C/C++)