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