/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 может быть оптимизирована, если компилятор определяет, что функция вызывает только неисключаемыеthrow функции. Этот параметр обеспечивает строгое соответствие 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++ равно thrown.

Обработка исключений 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 синтаксис. Дополнительные сведения см. в разделе "Структурированная обработка исключений".

Важно!

Указание и tryобработка /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. В этом примере создается структурированное исключение:catch

// 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. По умолчанию среда выполнения проверка может быть оптимизирована, если серверная часть компилятора определяет, что функция вызывает только функции, отличныеthrow от ing. throwФункции, отличные от ing, являются любыми функциями, имеющими атрибут, который указывает, что исключения не могут быть thrown. Они включают функции, помеченные noexcept, __declspec(nothrow)throw()и, когда /EHc указано, extern "C" функции. Функции, отличныеthrow от ing, также включают все, что компилятор определил, неthrow является ing путем проверки. Вы можете явно задать поведение по умолчанию с помощью /EHr-.

Атрибут, отличныйthrow от ing, не является гарантией того, что исключения не могут быть thrown функцией. В отличие от поведения noexcept функции, компилятор MSVC рассматривает исключение thrown функцией, объявленной с помощью 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++)