Оператор try-except (C)
Только для систем Майкрософт
Оператор try-except
— это расширение Майкрософт на языке C, которое позволяет приложениям получать контроль над программой при обычном завершении выполнения событий. Такие события вызываются исключениями, а механизм, предназначенный для работы с ними, называется структурированной обработкой исключений.
Исключения могут вызываться аппаратными или программными средствами. Даже если работу приложения после таких исключений нельзя полностью восстановить, структурированная обработка исключений позволяет записать и отобразить информацию об ошибке. Также полезно зафиксировать внутреннее состояние приложения, чтобы выполнить диагностику проблемы. В частности, это помогает при возникновении периодических проблем, которые сложно воспроизводить.
Синтаксис
try-except-statement
:
__try
compound-statement
__except (
expression
)
compound-statement
Составной оператор после предложения __try
— это защищенный раздел. Составной оператор после предложения __except
— это обработчик исключений. Обработчик определяет набор действий, предпринимаемых при возникновении исключения во время выполнения защищенного раздела. Выполнение происходит следующим образом:
Сначала выполняется защищенный раздел.
Если исключение при этом не возникает, выполнение переходит в инструкцию, стоящую после предложения
__except
.Если исключение возникло во время выполнения защищенного раздела или в любой процедуре, вызываемой защищенным разделом, вычисляется выражение
__except
. Способ обработки исключения определяется возвращенным значением. Есть три возможных значения :EXCEPTION_CONTINUE_SEARCH
: исключение не распознано. Продолжайте поиск по стеку обработчика, сначала для содержащихtry-except
операторов, а затем обработчиков со следующим самым высоким приоритетом.EXCEPTION_CONTINUE_EXECUTION
: исключение распознается, но отклонено. Выполнение продолжается в точке, в которой возникло исключение.EXCEPTION_EXECUTE_HANDLER
Исключение распознано. Управление передается в обработчик исключений путем выполнения составного оператора__except
, а затем выполнение продолжается с точки, в которой возникло исключение.
Так как выражение __except
вычисляется как выражение C, оно ограничивается одиночным значением, оператором условного выражения или оператором "запятая". Если требуется более сложная обработка, выражение может вызывать процедуру, которая возвращает одно из этих трех значений.
Примечание.
Структурированная обработка исключений поддерживается с исходными файлами C и C++. Но она не предназначена специально для C++. Для переносимых программ C++ вместо структурированной обработки исключений следует использовать обработку исключений C++. Кроме того, механизм обработки исключений C++ обеспечивает намного более высокую гибкость, поскольку может обрабатывать исключения любого типа. Дополнительные сведения см. в разделе Обработка исключений в справочнике по языку C++.
Каждая процедура в приложении может иметь свой собственный обработчик исключений. Выражение __except
выполняется в области тела __try
. Оно имеет доступ ко всем локальным переменным, объявленным в этой области.
В блоке операторов __leave
можно использовать ключевое слово try-except
. Результат использования __leave
— переход в конец блока try-except
. Выполнение продолжается после окончания обработчика исключений. Хотя для получения того же результата можно использовать оператор goto
, он (оператор goto
) приводит к освобождению стека. Оператор __leave
более эффективен, так как он не вызывает раскрутку стека.
Выход из оператора try-except
с помощью функции времени выполнения longjmp
считается ненормальным завершением. Переход к оператору __try
недопустим, но выход из него допускается. Обработчик исключений не вызывается, если процесс удаляется во время выполнения оператора try-except
.
Пример
Ниже приведен пример обработчика исключений и обработчика завершения. Дополнительные сведения об обработчиках завершения см. в разделе Оператор try-finally
(С).
.
.
.
puts("hello");
__try {
puts("in try");
__try {
puts("in try");
RAISE_AN_EXCEPTION();
} __finally {
puts("in finally");
}
} __except( puts("in filter"), EXCEPTION_EXECUTE_HANDLER ) {
puts("in except");
}
puts("world");
Ниже показаны выходные данные для этого примера с комментариями справа:
hello
in try /* fall into try */
in try /* fall into nested try */
in filter /* execute filter; returns 1 so accept */
in finally /* unwind nested finally */
in except /* transfer control to selected handler */
world /* flow out of handler */
КОНЕЦ Только для систем Майкрософт