/EH
(модель обработки исключений)
Указывает поддержку модели обработки исключений, созданную компилятором. Аргументы указывают, следует ли применять catch(...)
синтаксис как к структурированным, так и к стандартным исключениям C++, предполагается лиextern применение кода C к throw исключениям и оптимизации определенных noexcept
проверок.
Синтаксис
/EHa
[-
]
/EHs
[-
]
/EHc
[-
]
/EHr
[-
]
Аргументы
a
Включает очистку стандартного стека C++ . Перехватывает как структурированные (асинхронные) так и стандартные исключения C++ (синхронные) при использовании catch(...)
синтаксиса. /EHa
переопределяет оба /EHs
аргумента и /EHc
аргументы.
s
Включает очистку стандартного стека C++ . Перехватывает только стандартные исключения C++ при использовании catch(...)
синтаксиса. Если /EHc
также не указано, компилятор предполагает, что функции, объявленные как extern "C" , могут throw вызывать исключение C++.
c
При использовании с /EHs
компилятором предполагается, что функции, объявленные как extern "C" , никогда не throw исключение C++. Он не действует при использовании с /EHa
(т /EHca
. е. эквивалентен /EHa
). /EHc
игнорируется, если /EHs
или /EHa
не задано.
r
Дает компилятору указание всегда создавать проверки завершения времени выполнения для всех функций noexcept
. По умолчанию, если компилятор определяет, что функция вызывает только функции, не создающие исключения, проверки времени выполнения для noexcept
могут быть исключены оптимизацией. Этот параметр обеспечивает строгое соответствие C++ по стоимости дополнительного кода. /EHr
игнорируется, если /EHs
или /EHa
не задано.
-
Очищает предыдущий аргумент параметра. Например, /EHsc-
интерпретируется как /EHs /EHc-
и эквивалентен /EHs
.
/EH
аргументы могут быть указаны отдельно или объединены в любом порядке. Если указано несколько экземпляров одного и того же аргумента, последний переопределяет все предыдущие. Например, то же самое, /EHr- /EHc /EHs
что /EHscr-
и , и имеет тот же эффект, что /EHscr
и /EHscr- /EHr
.
Замечания
Поведение обработки исключений по умолчанию
Компилятор всегда создает код, поддерживающий асинхронную обработку структурированных исключений (SEH). По умолчанию (то есть, если нет /EHsc
, /EHs
или /EHa
параметр указан), компилятор поддерживает SEH обработчики в собственном предложении C++ catch(...)
. Однако он также создает код, который частично поддерживает исключения C++. Код очистки исключений по умолчанию не уничтожает автоматические объекты C++ за пределами try
блоков, которые выходят из области из-за исключения. Утечки ресурсов и неопределенное поведение могут привести к возникновению исключения C++.
Обработка исключений C++ уровня "Стандартный"
Полная поддержка компилятора модели обработки исключений C++ уровня "Стандартный", которая безопасно распаковывает объекты стека (рекомендуется /EHsc
), /EHs
или /EHa
.
Если вы используете /EHs
или /EHsc
, catch(...)
то предложения не catch асинхронные структурированные исключения. Все нарушения доступа и управляемые System.Exception исключения проходят неуловимые. И объекты в области, когда происходит асинхронное исключение, не уничтожаются, даже если код обрабатывает асинхронное исключение. Это поведение является аргументом для выхода структурированных исключений без обработки. Вместо этого рассмотрим эти исключения неустранимые.
При использовании /EHs
или /EHsc
компилятор предполагает, что исключения могут возникать только при операторе throw
или при вызове функции. Это предположение позволяет компилятору исключить код для отслеживания времени существования многих неуправляемых объектов, что может значительно уменьшить размер кода. При использовании /EHa
исполняемый образ может быть более большим и медленным, так как компилятор не оптимизирует try
блоки так агрессивно. Он также оставляет в фильтрах исключений, которые автоматически очищают локальные объекты, даже если компилятор не видит какого-либо кода, который может throw вызывать исключение C++.
Структурированная и стандартная обработка исключений C++
Параметр /EHa
компилятора включает очистку безопасного стека как для асинхронных исключений, так и для исключений C++. Она поддерживает обработку стандартных исключений C++ и структурированных исключений с помощью собственного предложения C++ catch(...)
. Для реализации SEH без указания /EHa
можно использовать __try
__except
синтаксис и __finally
синтаксис. Дополнительные сведения см. в разделе "Структурированная обработка исключений".
Внимание
Указание /EHa
и попытка обработки всех исключений с помощью catch(...)
может быть опасной. В большинстве случаев восстановление после асинхронного исключения невозможно, и такие исключения следует считать неустранимыми. При их перехвате и продолжении работы возможно повреждение процесса и возникновение ошибок, которые трудно обнаружить и исправить.
Несмотря на поддержку SEHWindows и Visual C++, настоятельно рекомендуется использовать обработку исключений C++ стандарта ISO (/EHsc
или /EHs
). Это делает код более переносимым и гибким. Иногда может потребоваться использовать SEH устаревший код или для определенных типов программ. Это необходимо в коде, скомпилированном для поддержки среды CLR (/clr
например. Дополнительные сведения см. в разделе "Структурированная обработка исключений".
Рекомендуется никогда не связывать файлы объектов, скомпилированные с /EHa
помощью скомпилированных или /EHs
/EHsc
в одном исполняемом модуле. Если необходимо обработать асинхронное исключение с помощью /EHa
любого места в модуле, используйте /EHa
для компиляции всего кода в модуле. Синтаксис обработки структурированных исключений можно использовать в том же модуле, что и код, скомпилированный с помощью /EHs
. Однако синтаксис нельзя смешивать SEH с C++ try
throw
и catch
в той же функции.
Используйте, /EHa
если вы хотите, чтобы catch исключение, вызываемое чем-то другое throw
. В этом примере создается и перехватывается структурированное исключение:
// 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;
}
}
Обработка исключений в /clr
Этот /clr
параметр подразумевает /EHa
(то есть /clr /EHa
является избыточным). Компилятор создает ошибку, если /EHs
или /EHsc
используется после /clr
. Оптимизация не влияет на это поведение. При перехвате исключения компилятор вызывает деструкторы классов для всех объектов, которые находятся в той же области, что и исключение. Если исключение не поймано, эти деструкторы не выполняются.
Сведения об ограничениях обработки исключений /clr
см. в _set_se_translator.
Проверки исключений среды выполнения
Параметр /EHr
принудительно проверяет завершение среды выполнения во всех функциях с атрибутом noexcept
. По умолчанию проверки среды выполнения могут быть оптимизированы, если серверная часть компилятора определяет, что функция вызывает только неисполнение функций. К функциям, не создающим исключения, относятся все функции с атрибутом, указывающим, что исключения не создаются. Они включают функции, помеченные noexcept
, __declspec(nothrow)
throw()
и, когда /EHc
указано, extern "C"
функции. К функциям, не создающим исключения, также относятся функции, которые компилятор путем проверки определяет как не создающие исключения. Вы можете явно задать поведение по умолчанию с помощью /EHr-
.
Неисключаемый атрибут не гарантирует, что исключения не могут быть вызваны функцией. В отличие от поведения noexcept
функции, компилятор MSVC рассматривает исключение, созданное функцией, объявленной с помощью throw()
, __declspec(nothrow)
или extern "C"
как неопределенное поведение. Функции, использующие эти три атрибута объявления, не применяют проверки завершения среды выполнения для исключений. Вы можете использовать /EHr
этот параметр, чтобы определить это неопределенное поведение, заставив компилятора создавать проверки среды выполнения для необработанных исключений, которые экранируют noexcept
функцию.
Установка параметра в Visual Studio или программным способом
Установка данного параметра компилятора в среде разработки Visual Studio
Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.
Выберите свойства>конфигурации C/C++>Code Generation.
Измените значение свойства Включить C++ исключения .
Можно также задать для параметра Включить C++ исключения значение Нет, а затем на странице свойств Командная строка в поле Дополнительные параметры добавить параметр компилятора.
Установка данного параметра компилятора программным способом
- См. раздел ExceptionHandling.
См. также
Параметры компилятора MSVC
Синтаксис командной строки компилятора MSVC
Ошибки и обработка исключений
Спецификации исключений (throw)
Structured Exception Handling (C/C++)