Freigeben über


/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 /EHsdem 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, /EHsoder /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), /EHsoder /EHa.

Wenn Sie die Klauseln verwenden /EHs oder/EHsccatch(...), 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 __trySyntax __exceptverwenden./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++ tryund throwcatch in derselben Funktion kombinieren.

Verwenden Sie /EHa diesen Wert, wenn Sie eine Ausnahme verwenden catch möchten, die von einer anderen Ausnahme als einer throwausgelö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

  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 konfigurationseigenschaften>C/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 Compiler-Befehlszeilensyntax
Modernes C++: Best Practices für Ausnahmen und Fehlerbehandlung
Ausnahmespezifikationen (throw)
Structured Exception Handling (C/C++)