/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 /EHs
funkcji 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 /EHsc
nie określono opcji , /EHs
lub /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), /EHs
lub /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 /EHa
wykonywalnego , 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ć __try
składni , __except
i __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
, throw
i 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 /clr
obszarze , 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
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).
Wybierz pozycję Właściwości konfiguracji>Generowanie kodu C/C>++.
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: ExceptionHandling.
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++)