Оператор try-finally
Блок, относящийся только к системам Microsoft
Следующий синтаксис описывает оператор try-finally:
__try {
// guarded code
}
__finally {
// termination code
}
Грамматика
оператор-try-finally:
__try составной-оператор__finally составной-оператор
Оператор try-finally является расширением Microsoft для языков C и С++ и позволяет целевым приложениям гарантировать выполнение кода очистки при прерывании выполнения блока кода. Очистка включает такие задачи, как отмена распределения памяти, закрытие файлов и освобождение их дескрипторов. Оператор try-finally особенно полезен для подпрограмм, в которых в нескольких местах выполняется проверка на наличие ошибок, способных вызвать преждевременное возвращение из подпрограммы.
Сопутствующую информацию и пример кода см. в разделе Оператор try-except. Дополнительные сведения о структурированной обработке исключений в общем см. в разделе Структурная обработка исключений. Дополнительные сведения об обработке исключений в управляемых приложениях см. в разделе Обработка исключений в /clr.
Примечание
Структурированная обработка исключений поддерживается в Win32 для исходных файлов как на C, так и на C++.Однако она не предназначена специально для C++.Для того чтобы ваш код лучше переносился, лучше использовать механизм обработки исключений языка C++.Кроме того, этот механизм отличается большей гибкостью, поскольку может обрабатывать исключения любого типа.В программах на языке C++ рекомендуется использовать механизм обработки исключений C++ (операторы try, catch и throw).
Составной оператор после предложения __try представляет собой защищенный раздел. Составной оператор после предложения __finally является обработчиком завершения. Такой обработчик определяет набор действий, выполняемых при выходе из защищенного раздела независимо от того, происходит ли выход в результате исключения (ненормальное завершение) или в результате стандартной передачи управления дальше (нормальное завершение).
Управление достигает оператора __try в процессе обычного последовательного выполнения (передачи управления дальше). Если элемент управления входит в __try, становится активным соответствующий обработчик. Если поток элементов управления достигает конца блока try, выполнение продолжается следующим образом.
Вызывается обработчик завершения.
По окончании работы обработчика завершения выполнение продолжается после оператора __finally. Независимо от того как завершается защищенный раздел (например, оператором goto выхода из защищенного тела или оператором return), обработчик завершения выполняется перед (before) выходом потока элементов управления из защищенного раздела.
Оператор __finally не блокирует поиск соответствующего обработчика исключений.
Если исключение возникает в блоке __try, операционная система должна найти обработчик для исключения, либо программа завершится ошибкой. Если обработчик найден, любые и все блоки __finally выполняются и выполнение продолжается в обработчике.
Например, предположим, ряд вызовов функций связывает функцию А с функцией D, как показано на следующем рисунке. Каждая функция имеет один обработчик завершения. Если исключение создается в функции D и обрабатывается в функции А, обработчики завершения вызываются в том порядке, в котором система освобождает стек: D, C и B.
Порядок выполнения обработчиков завершения
Примечание
Поведение оператора try-finally отличается от некоторых других языков, поддерживающих использование оператора finally, например C#. Один оператор __try может иметь либо __finally, либо __except, но не оба. Если оба следует использовать одновременно, оператор try-except должен включать внутренней оператор try-finally. Правила,задающие время выполнения каждого блока, также различаются.
Ключевое слово __leave
Ключевое слово __leave может использоваться только в защищенном разделе оператора try-finally. Оно приводит к тому, что выполнение переходит в конец защищенного раздела. Выполнение продолжается с первого оператора в обработчике завершения.
Оператор goto может также выйти из защищенного раздела, однако в этом случае производительность снизится, поскольку будет вызвано освобождение стека. Оператор __leave более эффективен, поскольку не вызывает освобождение стека.
Аварийное завершение
Выход из оператора try-finally с помощью функции времени выполнения longjmp считается ненормальным завершением. Переход к оператору __try недопустим, но допустим выход из него. Все операторы __finally, которые активны между отправным пунктом (нормальным завершением блока __try) и точкой назначения (блоком __except, обрабатывающим исключение), должны быть запущены. Это называется "локальной раскруткой".
Если блок try по какой-либо причине завершается преждевременно (включая выход из блока), система выполняет связанный блок finally в рамках освобождения стека. В этих случаях функция AbnormalTermination возвращает значение TRUE, если вызывается из блока finally; в противном случае она возвращает значение FALSE.
Если в процессе выполнения оператора try-finally процесс удаляется, обработчик завершения не вызывается.
Завершение блока, относящегося только к системам Microsoft
См. также
Ссылки
Написание обработчика завершения