Параметр /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

  1. Откройте диалоговое окно Страницы свойств проекта. Дополнительные сведения см. в разделе Открытие свойств страниц проекта.

  2. В левой области разверните узел Свойства конфигурации, C/C++, Создание кода.

  3. Измените значение свойства Включить C++ исключения.

    Можно также задать для параметра Включить C++ исключения значение Нет, а затем на странице свойств Командная строка в поле Дополнительные параметры добавить параметр компилятора.

Установка данного параметра компилятора программным способом

См. также

Ссылки

Параметры компилятора

Настройка параметров компилятора

Спецификации исключений

Структурированная обработка исключений (C/C++)

Основные понятия

Обработка ошибок и исключений (современный C++)