Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Структурированная обработка исключений (SEH) — это расширение Майкрософт для C и C++ для обработки определенных исключительных ситуаций кода, таких как ошибки оборудования, корректно. Хотя Windows и Microsoft C++ поддерживают SEH, рекомендуется использовать обработку исключений C++ стандарта ISO в коде C++. Это делает код более переносимым и гибким. Однако для поддержания существующего кода или для определенных типов программ может потребоваться использовать SEH.
Корпорация Майкрософт:
Грамматика
try-except-statement:
__trycompound-statement__except(filter-expression)compound-statement
try-finally-statement:
__trycompound-statement__finallycompound-statement
Замечания
С помощью SEH можно убедиться, что ресурсы, такие как блоки памяти и файлы, будут освобождены правильно, если выполнение неожиданно завершается. Вы также можете справиться с конкретными проблемами ( например, недостаточной памяти), используя краткий структурированный код, который не зависит от goto инструкций или сложного тестирования кодов возврата.
Инструкции try-except , try-finally упомянутые в этой статье, являются расширениями Майкрософт на языках C и C++. Они поддерживают SEH, позволяя приложениям получать контроль над программой после событий, которые в противном случае завершают выполнение. Хотя SEH работает с исходными файлами C++, он не предназначен специально для C++. Если вы используете SEH в программе C++, которая компилируется с помощью /EHa или /EHsc параметром, деструкторы для локальных объектов вызываются, но другое поведение выполнения может не быть ожидаемым. Пример см. далее в этой статье. В большинстве случаев вместо SEH рекомендуется использовать обработку исключений C++ стандарта ISO. С помощью обработки исключений C++ можно убедиться, что код более переносим, и вы можете обрабатывать исключения любого типа.
Если у вас есть код C, использующий SEH, можно смешать его с кодом C++, использующим обработку исключений C++. Дополнительные сведения см. в разделе "Обработка структурированных исключений" в C++.
Существует два механизма SEH:
Обработчики исключений или
__exceptблоки, которые могут реагировать на исключение или закрывать его в зависимости отfilter-expressionзначения. Дополнительные сведения смtry-except. в инструкции.Обработчики завершения или
__finallyблоки, которые всегда вызываются, вызывается ли исключение. Дополнительные сведения смtry-finally. в инструкции.
Эти два типа обработчиков отличаются, но тесно связаны с процессом, известным как очистка стека. При возникновении структурированного исключения Windows ищет последний установленный обработчик исключений, который сейчас активен. Обработчик может выполнить одно из трех действий:
Не удается распознать исключение и передать управление другим обработчикам (
EXCEPTION_CONTINUE_SEARCH).Распознать исключение, но закрыть его (
EXCEPTION_CONTINUE_EXECUTION).Распознайте исключение и обработайте его (
EXCEPTION_EXECUTE_HANDLER).
Обработчик исключений, распознающий исключение, может не находиться в функции, которая выполнялась при возникновении исключения. Он может находиться в функции гораздо выше в стеке. Запущенная в данный момент функция и все остальные функции в кадре стека завершаются. Во время этого процесса стек раскучен. То есть локальные нестатические переменные завершенных функций очищаются из стека.
По мере очистки стека операционная система вызывает все обработчики завершения, написанные для каждой функции. Используя обработчик завершения, вы очищаете ресурсы, которые в противном случае останутся открытыми из-за ненормального завершения. Если вы ввели критически важный раздел, его можно выйти из обработчика завершения. Когда программа завершит работу, вы можете выполнять другие задачи по обслуживанию дома, такие как закрытие и удаление временных файлов.
Дальнейшие шаги
Пример
Как упоминалось ранее, деструкторы для локальных объектов вызываются, если вы используете SEH в программе C++ и компилируете его с помощью /EHa или /EHsc параметра. Однако поведение во время выполнения может не быть ожидаемым, если вы также используете исключения C++. В этом примере показаны эти различия в поведении.
#include <stdio.h>
#include <Windows.h>
#include <exception>
class TestClass
{
public:
~TestClass()
{
printf("Destroying TestClass!\n");
}
};
__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
printf("Throwing C++ exception\n");
throw std::exception("");
#else
printf("Triggering SEH exception\n");
volatile int *pInt = 0x00000000;
*pInt = 20;
#endif
}
__declspec(noinline) void TestExceptions()
{
TestClass d;
TestCPPEX();
}
int main()
{
__try
{
TestExceptions();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("Executing SEH __except block\n");
}
return 0;
}
Если вы используете /EHsc для компиляции этого кода, но макрос CPPEX локального элемента управления тестом не определен, TestClass деструктор не выполняется. Результат выглядит следующим образом:
Triggering SEH exception
Executing SEH __except block
Если вы используете /EHsc для компиляции кода и CPPEX определяется с помощью /DCPPEX (поэтому создается исключение C++), TestClass выполняется деструктор и выходные данные выглядят следующим образом:
Throwing C++ exception
Destroying TestClass!
Executing SEH __except block
Если вы используете /EHa для компиляции кода, TestClass деструктор выполняет выполнение исключения с помощью стандартного выражения C++ throw или SEH. То есть определяется ли CPPEX он. Результат выглядит следующим образом:
Throwing C++ exception
Destroying TestClass!
Executing SEH __except block
Дополнительные сведения см. в разделе /EH (Модель обработки исключений)
END Microsoft-specific
См. также
Обработка исключений
Ключевые слова
<exception>
Ошибки и обработка исключений
Структурированная обработка исключений (Windows)