/EH (Ausnahmebehandlungsmodell)

Gibt die vom Compiler generierte Ausnahmebehandlungsmodellunterstützung an. Argumente geben ancatch(...), ob Syntax sowohl auf strukturierte als auch auf standardmäßige C++-Ausnahmen angewendet werden soll, extern ob "C"throw-Code als Ausnahmen angenommen wird und ob bestimmte Überprüfungen optimiert werdennoexcept.

Syntax

/EHa[-]
/EHs[-]
/EHc[-]
/EHr[-]

Argumente

a
Aktiviert die standardmäßige C++-Stapelentladung. Fängt sowohl strukturierte (asynchrone) als auch standardmäßige C++-Ausnahmen (synchron) ab, wenn Sie Syntax catch(...) verwenden. /EHa überschreibt die Argumente /EHs und /EHc .

s
Aktiviert die standardmäßige C++-Stapelentladung. Fängt nur C++-Standardausnahmen ab, wenn Sie Syntax catch(...) verwenden. Sofern /EHc nicht auch angegeben wird, geht der Compiler davon extern aus, dass als "C" deklarierte Funktionen eine throw C++-Ausnahme sein können.

c
Bei Verwendung mit /EHsgeht der Compiler davon aus extern , dass Funktionen, die als "C" deklariert sind, nie throw eine C++-Ausnahme sind. Sie hat keine Auswirkungen, wenn sie mit /EHa verwendet wird (d /EHca . h. entspricht /EHa). /EHc wird ignoriert, wenn /EHs oder /EHa nicht angegeben sind.

r
Weist den Compiler an, immer Laufzeitbeendigungsprüfungen für alle noexcept -Funktionen zu generieren. Standardmäßig können Laufzeitüberprüfungen noexcept für nicht optimiert werden, wenn der Compiler bestimmt, dass die Funktion nur nicht-ing-Funktionenthrow aufruft. Diese Option bietet strenge C++-Konformität auf Kosten von zusätzlichem Code. /EHr wird ignoriert, wenn /EHs oder /EHa nicht angegeben sind.

-
Löschen des vorherigen Optionsarguments. Beispielsweise wird als /EHsc- interpretiert, /EHs /EHc-und entspricht /EHs.

/EH -Argumente können separat oder kombiniert in beliebiger Reihenfolge angegeben werden. Wenn mehr als eine Instanz desselben Arguments angegeben wird, überschreibt die letzte Instanz alle früheren. ist z. /EHr- /EHc /EHs B. identisch mit /EHscr-und hat /EHscr- /EHr die gleiche Auswirkung wie /EHscr.

Bemerkungen

Standardverhalten bei der Ausnahmebehandlung

Der Compiler generiert immer Code, der die asynchrone strukturierte Ausnahmebehandlung () unterstütztSEH. Standardmäßig (d. h., /EHscwenn keine Option , /EHsoder /EHa angegeben ist), SEH unterstützt der Compiler Handler in der nativen C++- catch(...) Klausel. Es wird jedoch auch Code generiert, der C++-Ausnahmen nur teilweise unterstützt. Der Standardcode für die Ausnahmeentladung zerstört keine automatischen C++ try -Objekte außerhalb von Blöcken, die aufgrund einer Ausnahme außerhalb des Gültigkeitsbereichs sind. Ressourcenlecks und nicht definiertes Verhalten können dazu führen, dass eine C++-Ausnahme thrown ist.

C++-Standardausnahmebehandlung

Vollständige Compilerunterstützung für das C++-Standard-Ausnahmebehandlungsmodell, das Stapelobjekte sicher entlädt /EHsc , erfordert (empfohlen), /EHsoder /EHa.

Wenn Sie oder /EHs verwenden /EHsc, sind ihre Klauseln catch(...) keine asynchronen strukturierten catch Ausnahmen. Zugriffsverletzungen und verwaltete System.Exception Ausnahmen werden nicht abgesagt. Objekte im Gültigkeitsbereich, wenn eine asynchrone Ausnahme auftritt, werden auch dann nicht zerstört, wenn der Code die asynchrone Ausnahme behandelt. Dieses Verhalten ist ein Argument, mit dem strukturierte Ausnahmen nicht behandelt werden. Betrachten Sie diese Ausnahmen stattdessen als schwerwiegende Ausnahmen.

Wenn Sie oder /EHs verwenden /EHsc, geht der Compiler davon aus throw , dass Ausnahmen nur bei einer -Anweisung oder bei einem Funktionsaufruf auftreten können. Diese Annahme ermöglicht es dem Compiler, Code zum Nachverfolgen der Lebensdauer vieler entladungsfähiger Objekte zu entfernen, wodurch die Codegröße erheblich reduziert werden kann. Wenn Sie verwenden /EHa, ist ihr ausführbares Image möglicherweise größer und langsamer, try da der Compiler Blöcke nicht so aggressiv optimiert. Außerdem werden Ausnahmefilter verwendet, die lokale Objekte automatisch bereinigen, auch wenn der Compiler keinen Code sieht, throw der eine C++-Ausnahme auslösen kann.

Strukturierte und standardmäßige C++-Ausnahmebehandlung

Die /EHa Compileroption ermöglicht eine sichere Stapelentladung sowohl für asynchrone Ausnahmen als auch für C++-Ausnahmen. Sie unterstützt die Behandlung von C++-Standardausnahmen und strukturierten Ausnahmen mithilfe der nativen C++- catch(...) Klausel. Um zu implementieren SEH , ohne /EHaanzugeben, können Sie die __trySyntax , __exceptund __finally verwenden. Weitere Informationen finden Sie unter Strukturierte Ausnahmebehandlung.

Wichtig

Das Angeben /EHa und tryFestlegen von , um alle Ausnahmen mithilfe von catch(...) 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.

Auch wenn Windows und Visual C++ SEHunterstützen, wird dringend empfohlen, die C++-Ausnahmebehandlung nach ISO-Standard ( oder )/EHsc zu verwenden/EHs. Dadurch wird Ihr Code portierbarer und flexibler. Es kann immer noch Zeiten geben, in der Sie SEH in Legacycode oder für bestimmte Arten von Programmen verwenden müssen. Dies ist beispielsweise in Code erforderlich, der zur Unterstützung der Common Language Runtime (/clr) kompiliert wurde. Weitere Informationen finden Sie unter Strukturierte Ausnahmebehandlung.

Es wird empfohlen, mit kompilierte Objektdateien /EHa/EHs/EHsc niemals mit Denkdateien zu verknüpfen, die mit oder im selben ausführbaren Modul kompiliert wurden. Wenn Sie eine asynchrone Ausnahme mithilfe /EHa einer beliebigen Stelle in Ihrem Modul behandeln müssen, verwenden Sie , /EHa um den ganzen Code im Modul zu kompilieren. Sie können die strukturierte Ausnahmebehandlungssyntax im selben Modul wie Code verwenden, der mit kompiliert wird /EHs. Sie können die Syntax jedoch nicht mit SEH C++ try, throwund in derselben catch Funktion kombinieren.

Verwenden /EHa Sie , wenn Sie eine catch Ausnahme verwenden möchten, die von einem anderen als ausgelöst wird throw. In diesem Beispiel wird eine strukturierte catchAusnahme generiert und ausgelöst:

// 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. h. /clr /EHa ist redundant). Der Compiler generiert einen Fehler, wenn /EHs oder /EHsc nach verwendet wird /clr. Optimierungen wirken sich nicht auf dieses Verhalten aus. Wenn eine Ausnahme erfasst wird, ruft der Compiler die Klassendetruktoren für alle Objekte auf, die sich im gleichen Bereich wie die Ausnahme befinden. Wenn eine Ausnahme nicht erfasst wird, werden diese Destruktoren nicht ausgeführt.

Informationen zu Einschränkungen bei der Ausnahmebehandlung unter finden /clrSie unter _set_se_translator.

Laufzeitausnahmeüberprüfungen

Die /EHr Option erzwingt Laufzeitbeendigungsprüfungen in allen Funktionen, die über ein -Attribut noexcept verfügen. Standardmäßig können Laufzeitüberprüfungen nicht optimiert werden, wenn das Compiler-Back-End feststellt, dass eine Funktion nur nicht-ing-Funktionenthrow aufruft . Nicht-ing-Funktionenthrow sind alle Funktionen, die über ein Attribut verfügen, das angibt, dass keine Ausnahmen n sein throwdürfen. Sie enthalten Funktionen, die noexceptmit , throw(), __declspec(nothrow)und gekennzeichnet sind, wenn /EHc angegeben ist, extern "C" Funktionen. Nicht-ing-Funktionenthrow schließen auch alle funktionen ein, die der Compiler ermittelt hat, sind durch Überprüfungthrow nicht ing-ing. Sie können das Standardverhalten explizit mithilfe von festlegen /EHr-.

Ein nicht ing-Attributthrow ist keine Garantie dafür, dass Ausnahmen nicht von throweiner Funktion n sein können. Im Gegensatz zum Verhalten einer Funktion noexceptthrowbetrachtet der MSVC Compiler eine Ausnahme n throw()durch eine Funktion, die mit , __declspec(nothrow)oder extern "C" deklariert wurde, als nicht definiertes Verhalten. Funktionen, die diese drei Deklarationsattribute verwenden, erzwingen keine Laufzeitbeendigungsprüfungen für Ausnahmen. Sie können die -Option /EHr verwenden, um dieses undefinierte Verhalten zu identifizieren, indem Sie den Compiler zwingen, Laufzeitüberprüfungen für nicht behandelte Ausnahmen zu generieren, die eine Funktion mit Escapefunktion noexcept escapen.

Festlegen der Option in Visual Studio programmgesteuert

So legen Sie diese Compileroption in der Visual Studio-Entwicklungsumgebung fest

  1. Ö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).

  2. Wählen Sie KonfigurationseigenschaftenC>/C++>Codegenerierung aus.

  3. Ä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 auch

MSVC Compileroptionen
MSVC Compilerbefehlszeilensyntax
Fehler und Ausnahmebehandlung
Ausnahmespezifikationen (throw)
Structured Exception Handling (C/C++)