Udostępnij za pośrednictwem


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

Określa obsługę modelu obsługi wyjątków wygenerowaną przez kompilator. Argumenty określają, czy należy zastosować catch(...) składnię zarówno do wyjątków ustrukturyzowanych, jak i standardowych wyjątków języka C++, czyextern "C" przyjmuje throw się wyjątki i czy należy zoptymalizować niektóre noexcept kontrole.

Składnia

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

Argumenty

a
Umożliwia odwijanie standardowego stosu języka C++. Przechwytuje zarówno ustrukturyzowane (asynchroniczne) jak i standardowe wyjątki języka C++ (synchroniczne) podczas korzystania ze catch(...) składni. /EHa zastępuje zarówno argumenty, jak /EHs i /EHc .

s
Umożliwia odwijanie standardowego stosu języka C++. Przechwytuje tylko standardowe wyjątki języka C++, gdy używasz catch(...) składni. Jeśli nie /EHc zostanie również określony, kompilator zakłada, że funkcje zadeklarowane jako extern "C" mogą throw być wyjątkiem języka C++.

c
W przypadku użycia z /EHsprogramem kompilator zakłada, że funkcje zadeklarowane jako extern "C" nigdy nie throw stanowią wyjątku języka C++. Nie ma żadnego efektu w przypadku użycia z elementem /EHa (oznacza to, /EHca że jest równoważne )./EHa /EHc wartość jest ignorowana, jeśli /EHs /EHa nie zostanie określona.

r
Informuje kompilator, aby zawsze generował testy zakończenia środowiska uruchomieniowego dla wszystkich noexcept funkcji. Domyślnie sprawdzanie noexcept środowiska uruchomieniowego może zostać zoptymalizowane, jeśli kompilator określi, że funkcja wywołuje tylko funkcje nierzucające. Ta opcja zapewnia ścisłą zgodność języka C++ kosztem dodatkowego kodu. /EHr wartość jest ignorowana, jeśli /EHs /EHa nie zostanie określona.

-
Czyści poprzedni argument opcji. Na przykład /EHsc- element jest interpretowany jako /EHs /EHc-, i jest odpowiednikiem /EHselementu .

/EH Argumenty mogą być określane oddzielnie lub połączone w dowolnej kolejności. Jeśli określono więcej niż jedno wystąpienie tego samego argumentu, ostatni zastępuje je we wcześniejszych. Na przykład /EHr- /EHc /EHs jest taka sama jak , i /EHscr- /EHr ma taki sam efekt jak /EHscr-/EHscr.

Uwagi

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

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

Standardowa obsługa wyjątków języka C++

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

Jeśli używasz /EHs klauzul lub /EHsc, catch(...) klauzule nie catch są asynchroniczne wyjątki ustrukturyzowane. Wszelkie naruszenia dostępu i wyjątki zarządzane System.Exception nie są przechwytywane. Obiekty w zakresie, gdy wystąpi wyjątek asynchroniczny, 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 krytyczne.

W przypadku używania instrukcji /EHs lub /EHsckompilator zakłada, że wyjątki mogą występować tylko w throw instrukcji lub wywołaniu funkcji. To założenie pozwala kompilatorowi wyeliminować kod do śledzenia okresu istnienia wielu niewiążalnych obiektów, co może znacznie zmniejszyć rozmiar kodu. Jeśli używasz /EHaelementu , obraz wykonywalny może być większy i wolniejszy, ponieważ kompilator nie optymalizuje try bloków tak agresywnie. Pozostawia również w filtrach wyjątków, które automatycznie czyszczą obiekty lokalne, nawet jeśli kompilator nie widzi żadnego kodu, który może throw być wyjątkiem języka C++.

Obsługa wyjątków ze strukturą i standardowym językiem C++

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

Ważne

Określanie /EHa i próba obsługi wszystkich wyjątków przy użyciu catch(...) metody może 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 systemy Windows i Visual C++ obsługują SEHsystem , zdecydowanie zalecamy używanie standardowej obsługi wyjątków C++ w standardzie ISO (/EHsc lub /EHs). Dzięki temu kod jest bardziej przenośny i elastyczny. Nadal może być konieczne użycie SEH w starszym kodzie lub w przypadku określonych rodzajów programów. Jest to wymagane w kodzie skompilowanym w celu obsługi środowiska uruchomieniowego języka wspólnego (/clr), na przykład. Aby uzyskać więcej informacji, zobacz Obsługa wyjątków strukturalnych.

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

Użyj polecenia /EHa , jeśli chcesz utworzyć catch wyjątek zgłaszany przez coś innego throwniż . Ten przykład generuje i wychwytuje 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 /clr

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

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

Sprawdzanie wyjątków środowiska uruchomieniowego

Opcja /EHr wymusza sprawdzanie zakończenia działania we wszystkich funkcjach, które mają noexcept atrybut. Domyślnie kontrole środowiska uruchomieniowego mogą być optymalizowane, jeśli zaplecze kompilatora określa, że funkcja wywołuje tylko funkcje nierzucające . Funkcje bez zgłaszania są funkcjami, które mają atrybut, który określa, że nie mogą być zgłaszane żadne wyjątki. Obejmują one funkcje oznaczone , noexcept, __declspec(nothrow)throw(), i, gdy /EHc jest określony, extern "C" funkcje. Funkcje bez zgłaszania obejmują również wszystkie, które zostały określone przez kompilator, nie są zgłaszane przez inspekcję. Domyślne zachowanie można jawnie ustawić za pomocą polecenia /EHr-.

Atrybut nie zgłaszający nie jest gwarancją, że wyjątki nie mogą być zgłaszane przez funkcję. W przeciwieństwie do zachowania noexcept funkcji kompilator MSVC uwzględnia wyjątek zgłaszany przez funkcję zadeklarowaną przy użyciu metody throw(), __declspec(nothrow)lub extern "C" jako niezdefiniowane zachowanie. Funkcje korzystające z tych trzech atrybutów deklaracji nie wymuszają sprawdzania zakończenia działania dla wyjątków. Możesz użyć /EHr opcji , aby ułatwić zidentyfikowanie tego niezdefiniowanego zachowania, zmuszając kompilator do generowania testów środowiska uruchomieniowego pod kątem noexcept nieobsługiwanych wyjątków, które unikną funkcji.

Ustaw opcję w programie 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 języka C++ i kompilowania w programie Visual Studio).

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

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

    Możesz też ustawić opcję Włącz wyjątki języka C++ na wartość Nie, a następnie na stronie właściwości Wiersza polecenia w polu Dodatkowe opcje dodaj opcję kompilatora.

Aby programowo ustawić tę opcję kompilatora

Zobacz też

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