инструкция 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и catchthrow операторы).

Составной оператор после предложения __try — это защищенный раздел. Составной оператор после предложения __finally является обработчиком завершения. Обработчик задает набор действий, выполняемых при выходе защищенного раздела, выход из защищенного раздела по исключению (ненормальное завершение) или по стандартному завершению (обычное завершение).

Управление переходит к оператору __try в процессе обычного последовательного выполнения (передачи управления дальше). При вводе элемента управления связанный __tryобработчик становится активным. Если поток элементов управления достигает конца блока try, выполнение продолжается следующим образом.

  1. Вызывается обработчик завершения.

  2. По окончании работы обработчика завершения выполнение продолжается после оператора __finally. Однако защищенный раздел заканчивается (например, через goto защищенный текст или return оператор), обработчик завершения выполняется до перехода потока управления из защищенного раздела.

    Оператор __finally не блокирует поиск соответствующего обработчика исключений.

Если исключение возникает в __try блоке, операционная система должна найти обработчик исключения или программа завершится ошибкой. Если обработчик найден, все блоки выполняются и __finally выполняются в обработчике.

Например, предположим, ряд вызовов функций связывает функцию А с функцией D, как показано на следующем рисунке. Каждая функция имеет один обработчик завершения. Если исключение создается в функции D и обрабатывается в функции А, обработчики завершения вызываются в том порядке, в котором система освобождает стек: D, C и B.

Diagram of the order of termination handler execution.

Схема начинается с функции 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++)
Ключевые слова
Синтаксис обработчика завершения