Синтаксис обработчика завершения
Для создания обработчика завершения используются __try и __finally ключевое слово. В следующем примере показана структура обработчика завершения.
__try
{
// guarded body of code
}
__finally
{
// __finally block
}
Примеры см. в разделе "Использование обработчика завершения".
Как и в обработчике исключений, как блок __try, так и блок __finally требуют фигурных скобок ({}), и использование инструкции goto для перехода в любой блок запрещено.
Блок __try содержит защищенный текст кода, защищенный обработчиком завершения. Функция может иметь любое количество обработчиков завершения, и эти блоки обработки завершения могут быть вложены в одну функцию или в разные функции.
Блок __finally выполняется всякий раз, когда поток управления покидает блок __try . Однако блок __finally не выполняется при вызове любой из следующих функций в блоке __try: ExitProcess, ExitThread или прерывание.
Блок __finally выполняется в контексте функции, в которой находится обработчик завершения. Это означает, что блок __finally может получить доступ к локальным переменным этой функции. Выполнение блока __finally может завершиться любым из следующих средств.
- Выполнение последней инструкции в блоке и продолжение следующей инструкции
- Использование инструкции элемента управления (return, break, continue или goto)
- Использование longjmp или переход к обработчику исключений
Если выполнение блока __try завершается из-за исключения, вызывающего блок обработки исключений обработчика исключений на основе кадра, __finally блок выполняется перед выполнением блока обработки исключений. Аналогичным образом вызов функции библиотеки времени выполнения longjmp C из блока __try приводит к выполнению блока __finally до возобновления выполнения в целевом объекте операции longjmp . Если __try выполнение блока завершается из-за инструкции элемента управления (return, break, continue или goto), выполняется блок __finally .
Функция AbnormalTermination может использоваться в блоке __finally, чтобы определить, завершается ли блок __try последовательно, то есть достигается ли закрывающая скобка (}). Выход из блока __try из-за вызова longjmp, перехода к обработчику исключений или возврату, разрыву, продолжению или оператору goto считается ненормальным завершением. Обратите внимание, что сбой последовательного завершения приводит к тому, что система выполняет поиск по всем кадрам стека в обратном порядке, чтобы определить, должны ли вызываться обработчики завершения. Это может привести к снижению производительности из-за выполнения сотен инструкций.
Чтобы избежать ненормального завершения обработчика завершения, выполнение должно продолжаться до конца блока. Вы также можете выполнить инструкцию __leave . Оператор __leave позволяет немедленно прекратить __try блок без ненормального завершения и его штрафа за производительность. Проверьте документацию компилятора, чтобы определить, поддерживается ли инструкция __leave .
Если выполнение блока __finally завершается из-за инструкции возвращаемого элемента управления, он эквивалентен закрытию фигурной скобки в заключающей функции. Таким образом, включающая функция возвращается.