Compartilhar via


Instrução try-finally

Específico da Microsoft

A sintaxe a seguir descreve a instrução try-finally:

__try {
   // guarded code
}
__finally {
   // termination code
}

Gramática

  • try-finally-statement:
    __try compound-statement

    __finally compound-statement

A instrução try-finally é uma extensão da Microsoft para as linguagens C e C++ que permite que aplicativos de destino garantam a execução do código de limpeza quando a execução de um bloco de códigos é interrompida. A limpeza consiste em tarefas como desalocar memória, fechar arquivos e liberar identificadores de arquivos. A instrução try-finally é especialmente útil para rotinas que têm vários locais onde uma verificação é feita para um erro que pode causar o retorno prematuro da rotina.

Para obter informações relacionadas e um exemplo de código, consulte a instrução try-except. Para obter mais informações sobre o tratamento de exceções estruturado em geral, consulte Tratamento de exceções estruturado. Para obter mais informações sobre o tratamento de exceções em aplicativos gerenciados, consulte Tratamento de exceções em /clr.

Dica

A manipulação de exceção estruturada funciona com Win32 para arquivos de código-fonte em C e C++.No entanto, não é projetada especificamente para C++.Você pode garantir que o código seja mais portátil usando a manipulação de exceção de C++.Além disso, a manipulação de exceção de C++ é mais flexível, pois pode tratar exceções de qualquer tipo.Para programas C++, é recomendável usar o mecanismo de manipulação de exceção de C++ (instruções try, catch e throw).

A instrução composta após a cláusula __try é a seção protegida. A instrução composta após a cláusula __finally é o manipulador de término. O manipulador especifica um conjunto de ações que são executadas quando você sai da seção protegida, independentemente de a saída da seção protegida ser realizada por uma exceção (encerramento anormal) ou por queda padrão (encerramento normal).

O controle atinge a instrução __try em uma execução sequencial simples (queda). Quando o controle entra em __try, seu manipulador associado fica ativo. Se o fluxo de controle chegar ao fim do bloco try, a execução continuará da seguinte maneira:

  1. O manipulador de término é invocado.

  2. Quando o manipulador de término é concluído, a execução continua após a instrução __finally. Independentemente de como a seção protegida é encerrada (por exemplo, por meio de um goto fora do corpo protegido ou de uma instrução return), o manipulador de encerramento é executado before que o fluxo de controle sai da seção protegida.

    Uma instrução __finally não bloqueia a procura por um manipulador de exceção apropriado.

Se ocorrer uma exceção no bloco __try, o sistema operacional deve localizar um manipulador para a exceção. Caso contrário, o programa falhará. Se um manipulador for encontrado, todos os blocos __finally serão executados, e a execução será retomada no manipulador.

Por exemplo, imagine que uma série de chamadas de função vincula a função A à função D, conforme mostrado na figura a seguir. Cada função tem um manipulador de encerramento. Se uma exceção é gerada na função D e tratada na A, os manipuladores de encerramento são chamados nessa ordem à medida que o sistema desenrola a pilha: D, C, B.

Ordem de execução do manipulador de encerramento

Ordem de execução do manipulador de término

Dica

O comportamento de try-finally é diferente do de outras linguagens que oferecem suporte ao uso de finally, como C#. Um único __try pode ter __finally ou __except, mas não ambos. Se ambos devem ser usados juntos, uma instrução try-except externa deve incluir a instrução interna try-finally. As regras que especificam quando cada bloco é executado também são diferentes.

A palavra-chave __leave

A palavra-chave __leave é válida somente na seção protegida de uma instrução try-finally, e seu efeito é ir diretamente para o final da seção protegida. A execução continua na primeira instrução do manipulador de encerramento.

Uma instrução goto também pode sair da seção protegida, mas prejudica o desempenho porque invoca o desenrolamento da pilha. A instrução __leave é mais eficiente porque não causa o desenrolamento da pilha.

encerramento anormal

Sair de uma instrução try-finally usando a função de tempo de execução longjmp é considerado um encerramento anormal. Não é permitido ir para uma instrução __try, mas é permitido sair de uma. Todas as instruções __finally que estão ativas entre o ponto de partida (encerramento normal do bloco __try) e o destino (o bloco __except que trata a exceção) devem ser executadas. Isso se chama desenrolamento local.

Se um bloco try é encerrado prematuramente por qualquer motivo, incluindo uma saída do bloco, o sistema executa o bloco finally associado como parte do processo de desenrolamento da pilha. Nesses casos, a função AbnormalTermination retorna TRUE se chamada de dentro do bloco finally; caso contrário, ela retorna FALSE.

O manipulador de encerramento não é chamado se um processo é interrompido no meio da execução de uma instrução try-finally.

FIM de Específico da Microsoft

Consulte também

Referência

Escrevendo um manipulador de término

Tratamento de exceções estruturado (C/C++)

Palavras-chave C++

Termination-Handler Syntax