/EH (Model obsługi wyjątków)

Określa obsługę modelu obsługi wyjątków wygenerowaną przez kompilator. Argumenty określają, catch(...) czy stosować składnię zarówno do ustrukturyzowanych, jak i standardowych wyjątków języka C++, extern czy zakłada się, że kod "C" jest przyjmowany jako throw wyjątki, oraz czy należy zoptymalizować niektóre kontrolenoexcept.

Składnia

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

Argumenty

a
Umożliwia odwijanie stosu standardowego języka C++. Przechwytuje zarówno strukturalne (asynchroniczne), jak i standardowe wyjątki C++ (synchroniczne), gdy używasz składni catch(...) . /EHa Zastępuje zarówno argumenty /EHs , jak i /EHc .

s
Umożliwia odwijanie stosu standardowego języka C++. Przechwytuje tylko standardowe wyjątki C++ w przypadku używania catch(...) składni. O /EHc ile nie określono również inaczej, kompilator zakłada, że funkcje zadeklarowane jako extern "C" mogą throw być wyjątkiem języka C++.

c
W przypadku korzystania z /EHsfunkcji z , kompilator zakłada, że funkcje zadeklarowane jakoextern "C" nigdythrow nie są wyjątkiem języka C++. Nie dzieje się tak, gdy jest używana z /EHa (to oznacza, /EHca że jest odpowiednikiem /EHa). /EHc wartość jest ignorowana, /EHs jeśli /EHa wartość lub nie zostanie określona.

r
Informuje kompilator, aby zawsze generował testy zakończenia środowiska uruchomieniowego dla wszystkich noexcept funkcji. Domyślnie testy środowiska uruchomieniowego mogą noexcept być optymalizowane od razu, jeśli kompilator określi, że funkcja wywołuje tylko funkcjethrow inne niż ing. Ta opcja zapewnia ścisłą zgodność języka C++ kosztem dodatkowego kodu. /EHr wartość jest ignorowana, /EHs jeśli /EHa wartość lub nie zostanie określona.

-
Czyszczy poprzedni argument opcji. Na przykład jest /EHsc- interpretowany jako /EHs /EHc-, i jest odpowiednikiem /EHs.

/EH Argumenty można określić oddzielnie lub połączyć w dowolnej kolejności. Jeśli określono więcej niż jedno wystąpienie tego samego argumentu, ostatnie zastępuje wcześniejsze. Na przykład , /EHr- /EHc /EHs jest taka sama jak , /EHscr-i /EHscr- /EHr ma taki sam efekt jak /EHscr.

Uwagi

Domyślne zachowanie obsługi wyjątków

Kompilator zawsze generuje kod, który obsługuje asynchroniczną obsługę wyjątków strukturalnych (SEH). Domyślnie (czyli jeśli /EHscnie określono opcji , /EHslub /EHa ), SEH kompilator obsługuje programy obsługi w natywnej klauzuli C catch(...) ++. Jednak generuje również kod, który tylko częściowo obsługuje wyjątki języka C++. Domyślny kod odwijania wyjątków nie niszczy automatycznych obiektów C++ try poza blokami, które wychodzą poza zakres z powodu wyjątku. Wycieki zasobów i niezdefiniowane zachowanie mogą wystąpić, gdy wyjątek C++ to thrown.

Standardowa obsługa wyjątków C++

Pełna obsługa kompilatora dla standardowego modelu obsługi wyjątków C++, który bezpiecznie odwija obiekty stosu /EHsc , wymaga (zalecane), /EHslub /EHa.

Jeśli używasz lub /EHs/EHsc, klauzule catch(...) nie mają asynchronicznych wyjątków catch strukturalnych. Wszelkie naruszenia dostępu i wyjątki zarządzane System.Exception są nieprzechowywałe. Obiekty w zakresie w przypadku wystąpienia wyjątku asynchronicznego nie są niszczone, nawet jeśli kod obsługuje wyjątek asynchroniczny. To zachowanie jest argumentem dla pozostawienia nieobsługiwanych wyjątków strukturalnych. Zamiast tego należy wziąć pod uwagę te wyjątki jako krytyczne.

Gdy używasz lub /EHs/EHsc, kompilator zakłada, że wyjątki throw mogą wystąpić tylko w instrukcji lub w wywołaniu funkcji. To założenie umożliwia kompilatorowi wyeliminowanie kodu do śledzenia okresu istnienia wielu odwijalnych obiektów, co może znacznie zmniejszyć rozmiar kodu. Jeśli używasz pliku /EHawykonywalnego , obraz wykonywalny może być większy i wolniejszy, ponieważ kompilator nie optymalizuje try bloków tak agresywnie. Pozostawia również filtry wyjątków, które automatycznie oczyszczają obiekty lokalne, throw nawet jeśli kompilator nie widzi żadnego kodu, który może wyjątku języka C++.

Obsługa wyjątków strukturalnych i standardowych w języku C++

Opcja /EHa kompilatora umożliwia bezpieczne odwijanie stosu dla wyjątków asynchronicznych i wyjątków języka C++. Obsługuje obsługę zarówno standardowych wyjątków C++ jak i wyjątków strukturalnych przy użyciu natywnej klauzuli C catch(...) ++. Aby zaimplementować SEH bez określania /EHa, można użyć __tryskładni , __excepti __finally . Aby uzyskać więcej informacji, zobacz Structured exception handling (Obsługa wyjątków strukturalnych).

Ważne

Określanie i /EHa obsługa trywszystkich wyjątków przy użyciu funkcji może catch(...) być niebezpieczne. W większości przypadków wyjątki asynchroniczne są nie do odzyskania i powinny być uważane za krytyczne. Ich wychwytywanie i kontynuacja wykonania aplikacji może spowodować uszkodzenie procesu i prowadzić do błędów, które trudno znaleźć i naprawić.

Mimo że Windows i Visual C++ SEH, zdecydowanie zalecamy użycie obsługi wyjątków C++ standardu ISO (/EHsc lub /EHs). Dzięki temu kod jest bardziej przenośny i elastyczny. Czasami nadal może być trzeba używać w starszym SEH kodzie lub dla określonych rodzajów programów. Jest on wymagany w kodzie skompilowanym do obsługi środowiska uruchomieniowego języka wspólnego (/clr), na przykład. Aby uzyskać więcej informacji, zobacz Structured exception handling (Obsługa wyjątków strukturalnych).

Zalecamy, aby nigdy nie łączyć plików obiektów skompilowanych przy użyciu polecenia z /EHa plikami skompilowanym przy /EHs użyciu polecenia lub /EHsc w tym samym module wykonywalnym. Jeśli musisz obsłużyć wyjątek asynchroniczny przy użyciu dowolnego /EHa miejsca w module, użyj metody , /EHa aby skompilować cały kod w module. Składni obsługi wyjątków strukturalnych można używać w tym samym module co kod, który został skompilowany przy użyciu polecenia /EHs. Nie można jednak mieszać składni SEH z językami C++ try, throwi w catch tej samej funkcji.

Użyj /EHa , jeśli chcesz, catch aby wyjątek był wywoływany przez coś innego niż throw. Ten przykład generuje i catchgeneruje wyjątek strukturalny:

// 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;
    }
}

Obsługa wyjątków w obszarze /clr

Opcja /clr implikuje /EHa (to znaczy, że /clr /EHa jest nadmiarowa). Kompilator generuje błąd, jeśli element /EHs lub /EHsc jest używany po ./clr Optymalizacje nie wpływają na to zachowanie. Po przechwyceniu wyjątku kompilator wywołuje destruktory klas dla wszystkich obiektów, które znajdują się w tym samym zakresie co wyjątek. Jeśli wyjątek nie zostanie przechwycony, te destruktory nie będą uruchamiane.

Aby uzyskać informacje o ograniczeniach obsługi wyjątków w /clrobszarze , zobacz _set_se_translator.

Sprawdzanie wyjątków środowiska uruchomieniowego

Opcja /EHr wymusza sprawdzanie zakończenia środowiska uruchomieniowego we wszystkich funkcjach, które mają noexcept atrybut. Domyślnie testy środowiska uruchomieniowego mogą być optymalizowane od razu, jeśli wewnętrzne środowisko kompilatora ustali, że funkcja wywołuje tylko funkcjethrow inne niż ing. Funkcje innethrow niż ing to dowolne funkcje, które mają atrybut określający brak wyjątków, mogą mieć wartość thrown. Obejmują one funkcje oznaczone noexcept, throw(), __declspec(nothrow)i, jeśli jest /EHc określony, extern "C" funkcje. Funkcje innethrow niż ing obejmują również te, które kompilator ustalił,throw że nie są inspekcją. Domyślne zachowanie można jawnie ustawić przy użyciu funkcji /EHr-.

Atrybut niebędącythrow atrybutem ing nie jest gwarancją, że wyjątki nie mogą być thrown przez funkcję. W przeciwieństwie do zachowania funkcjinoexcept, kompilator MSVC throwtraktuje wyjątek n throw()przez funkcję zadeklarowaną przy użyciu , __declspec(nothrow)lub extern "C" jako niezdefiniowane zachowanie. Funkcje, które używają tych trzech atrybutów deklaracji, nie wymuszają sprawdzania zakończenia w czasie wykonywania dla wyjątków. Możesz użyć opcji , /EHr aby ułatwić identyfikację tego niezdefiniowanych zachowań, wymuś kompilatorowi wygenerowanie testów środowiska uruchomieniowego dla nieobsługiwanych wyjątków, które ucieczki dla noexcept funkcji.

Ustawianie opcji w Visual Studio lub programowo

Aby ustawić tę opcję kompilatora w środowisku programowania Visual Studio

  1. Otwórz okno dialogowe Strony właściwości projektu. Aby uzyskać szczegółowe informacje, zobacz Set C++ compiler and build properties in Visual Studio (Ustawianie właściwości kompilatora i kompilacji języka C++ w Visual Studio).

  2. Wybierz pozycję Właściwości konfiguracji>Generowanie kodu C/C>++.

  3. Zmodyfikuj właściwość Włącz wyjątki C++.

    Możesz też ustawić opcję Włącz wyjątki C++ na nie, a następnie na stronie właściwości Wiersz polecenia w polu Opcje dodatkowe dodać opcję kompilatora.

Aby programowo ustawić tę opcję kompilatora

Zobacz też

MSVC opcje kompilatora
MSVC składni wiersza polecenia kompilatora
Błędy i obsługa wyjątków
Specyfikacje wyjątków (throw)
Obsługa wyjątków strukturalnych (C/C++)