инструкция try-finally
Инструкция try-finally
— это расширение, которое поддерживает структурированную обработку исключений на языках C и C++.
Синтаксис
Следующий синтаксис описывает инструкцию try-finally
:
// . . .
__try {
// guarded code
}
__finally {
// termination code
}
// . . .
грамматики
try-finally-statement
:
__try
compound-statement
__finally
compound-statement
Инструкция try-finally
— это расширение Майкрософт на языках C и C++, которые позволяют целевым приложениям гарантировать выполнение кода очистки при прерывании выполнения блока кода. Очистка включает такие задачи, как отмена распределения памяти, закрытие файлов и освобождение их дескрипторов. Оператор try-finally
особенно полезен для подпрограмм, в которых в нескольких местах выполняется проверка на наличие ошибок, способных вызвать преждевременное возвращение из подпрограммы.
Дополнительные сведения и пример кода см try-except
. в инструкции. Дополнительные сведения о структурированной обработке исключений в целом см. в разделе "Структурированная обработка исключений". Дополнительные сведения об обработке исключений в управляемых приложениях с помощью C++/CLI см. в разделе /clr
"Обработка исключений".
Примечание.
Структурированная обработка исключений поддерживается в Win32 для исходных файлов как на C, так и на C++. Однако она не предназначена специально для C++. Для того чтобы ваш код лучше переносился, лучше использовать механизм обработки исключений языка C++. Кроме того, этот механизм отличается большей гибкостью, поскольку может обрабатывать исключения любого типа. Для программ C++ рекомендуется использовать механизм обработки исключений C++ (try
и catch
throw
операторы).
Составной оператор после предложения __try
— это защищенный раздел. Составной оператор после предложения __finally
является обработчиком завершения. Обработчик задает набор действий, выполняемых при выходе защищенного раздела, выход из защищенного раздела по исключению (ненормальное завершение) или по стандартному завершению (обычное завершение).
Управление переходит к оператору __try
в процессе обычного последовательного выполнения (передачи управления дальше). При вводе элемента управления связанный __try
обработчик становится активным. Если поток элементов управления достигает конца блока try, выполнение продолжается следующим образом.
Вызывается обработчик завершения.
По окончании работы обработчика завершения выполнение продолжается после оператора
__finally
. Однако защищенный раздел заканчивается (например, черезgoto
защищенный текст илиreturn
оператор), обработчик завершения выполняется до перехода потока управления из защищенного раздела.Оператор
__finally
не блокирует поиск соответствующего обработчика исключений.
Если исключение возникает в __try
блоке, операционная система должна найти обработчик исключения или программа завершится ошибкой. Если обработчик найден, все блоки выполняются и __finally
выполняются в обработчике.
Например, предположим, ряд вызовов функций связывает функцию А с функцией D, как показано на следующем рисунке. Каждая функция имеет один обработчик завершения. Если исключение создается в функции D и обрабатывается в функции А, обработчики завершения вызываются в том порядке, в котором система освобождает стек: D, C и B.
Схема начинается с функции A, которая вызывает функцию B, которая вызывает функцию C, которая вызывает функцию D. Функция D вызывает исключение. Затем обработчики завершения вызываются в этом порядке: обработчик завершения D, а затем C, а затем A обрабатывает исключение.
Порядок выполнения обработчика завершения
Примечание.
Поведение try-finally отличается от некоторых других языков, поддерживающих использование finally
, например C#. __try
Один может иметь либо, но не оба, __finally
и __except
. Если оба следует использовать одновременно, оператор try-except должен включать внутренней оператор try-finally. Правила,задающие время выполнения каждого блока, также различаются.
Для совместимости с предыдущими версиями _try
, _finally
и являются синонимами для __try
, __finally
и __leave
_leave
если не указан параметр /Za
компилятора (отключить расширения языка).
Ключевое слово __leave
__leave
Ключевое слово допустимо только в защищенном разделе try-finally
инструкции, и его эффект заключается в переходе к концу защищенного раздела. Выполнение продолжается с первого оператора в обработчике завершения.
Оператор goto
также может выскочить из защищенного раздела, но снижает производительность, так как вызывает стек очистки. Оператор __leave
является более эффективным, так как он не приводит к очистке стека.
Аварийное завершение
Выход из инструкции try-finally
с помощью функции времени выполнения longjmp считается ненормальным завершением. Переход к оператору __try
недопустим, но выход из него допускается. Все __finally
операторы, активные между точкой отъезда (обычное завершение __try
блока) и назначением ( __except
блок, обрабатывающий исключение), должны выполняться. Это называется локальной раскруткой.
__try
Если блок преждевременно завершается по какой-либо причине, включая переход из блока, система выполняет связанный __finally
блок в рамках процесса очистки стека. В таких случаях AbnormalTermination
функция возвращается true
при вызове __finally
из блока; в противном случае она возвращается false
.
Обработчик завершения не вызывается, если процесс убит в середине выполнения try-finally
инструкции.
КОНЕЦ Только для систем Майкрософт
См. также
Написание обработчика завершения
Structured Exception Handling (C/C++)
Ключевые слова
Синтаксис обработчика завершения