/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++ trythrowи 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

  1. Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.

  2. Выберите свойства>конфигурации C/C++>Code Generation.

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

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

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

См. также

Параметры компилятора MSVC
Синтаксис командной строки компилятора MSVC
Ошибки и обработка исключений
Спецификации исключений (throw)
Structured Exception Handling (C/C++)