Instrução try-finally
A instrução try-finally
é uma extensão específica da Microsoft que dá suporte ao tratamento de exceções estruturadas nas linguagens C e C++.
Sintaxe
A seguinte sintaxe 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 informações relacionadas e um exemplo de código, confira Instrução try-except
. Para mais informações sobre o tratamento de exceções estruturado em geral, confira Tratamento de exceções estruturado. Para mais informações sobre como lidar com exceções em aplicativos gerenciados com C++/CLI, confira Tratamento de exceção em /clr
.
Observação
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 (término anormal) ou por queda padrão (término 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:
O manipulador de término é invocado.
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 umgoto
fora do corpo protegido ou de uma instruçãoreturn
), o manipulador de encerramento é executado antes 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 __try
bloco, o sistema operacional deverá localizar um manipulador para a exceção ou 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.
O diagrama começa com a função A, que chama a função B, que chama a função C, que chama a função D. A função D gera uma exceção. Os manipuladores de terminação são então chamados nesta ordem: manipulador de terminação de D, C, B, e A manipula a exceção.
Ordem de execução do manipulador de terminação
Observação
O comportamento de try-finally é diferente do de outras linguagens que oferecem suporte ao uso de finally
, como C#. Um __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.
Para compatibilidade com versões anteriores, _try
, _finally
e _leave
são sinônimos de __try
, __finally
e __leave
, a menos que a opção do compilador /Za
(Desabilitar extensões de linguagem) esteja especificada.
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 Específico da Microsoft
Confira também
Escrevendo um manipulador de terminação
Tratamento de exceções estruturado (C/C++)
Palavras-chave
Sintaxe do manipulador de terminação
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de