Structured Exception Handling (C/C++)
Структурированная обработка исключений (SEH) — это расширение Майкрософт для C и C++ для обработки определенных исключительных ситуаций кода, таких как ошибки оборудования, корректно. Хотя Windows и Microsoft C++ поддерживают SEH, рекомендуется использовать обработку исключений C++ стандарта ISO в коде C++. Это делает код более переносимым и гибким. Однако для поддержания существующего кода или для определенных типов программ может потребоваться использовать SEH.
Только для систем Майкрософт:
грамматики
try-except-statement
:
__try
compound-statement
__except
(
filter-expression
)
compound-statement
try-finally-statement
:
__try
compound-statement
__finally
compound-statement
Замечания
С помощью SEH можно убедиться, что ресурсы, такие как блоки памяти и файлы, будут освобождены правильно, если выполнение неожиданно завершается. Вы также можете справиться с конкретными проблемами ( например, недостаточной памяти), используя краткий структурированный код, который не зависит от goto
инструкций или сложного тестирования кодов возврата.
Инструкции try-except
, try-finally
упомянутые в этой статье, являются расширениями Майкрософт на языках C и C++. Они поддерживают SEH, позволяя приложениям получать контроль над программой после событий, которые в иных ситуациях привели бы к завершению выполнения. Хотя обработка ошибок SEH работает с исходными файлами 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
(Модель обработки исключений)
КОНЕЦ Только для систем Майкрософт
См. также
Обработка исключений
Ключевые слова
<exception>
Ошибки и обработка исключений
Структурированная обработка исключений (Windows)
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по