/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 /EHs
programem 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 /EHs
elementu .
/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 /EHsc
określono opcji , /EHs
lub /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), /EHs
lub /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 /EHsc
kompilator 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 /EHa
elementu , 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 /EHa
parametru __try
, można użyć składni , __except
i __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
, throw
i catch
w tej samej funkcji.
Użyj polecenia /EHa
, jeśli chcesz utworzyć catch wyjątek zgłaszany przez coś innego throw
niż . 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
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).
Wybierz pozycję Właściwości>konfiguracji C/C++>Code Generation.
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: ExceptionHandling.
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++)