Sintaxe do manipulador de terminação
As palavras-chave __try e __finally são usadas para construir um manipulador de terminação. O exemplo a seguir mostra a estrutura de um manipulador de terminação.
__try
{
// guarded body of code
}
__finally
{
// __finally block
}
Para obter exemplos, consulte Usando um manipulador de terminação.
Assim como no manipulador de exceções, tanto o bloco __try quanto o bloco __finally exigem chaves ({}), e o uso de uma instrução goto para saltar para qualquer bloco não é permitido.
O bloco __try contém o corpo protegido do código que é protegido pelo manipulador de terminação. Uma função pode ter qualquer número de manipuladores de terminação, e esses blocos de manipulação de terminação podem ser aninhados na mesma função ou em funções diferentes.
O bloco __finally é executado sempre que o fluxo de controle sai do bloco __try . No entanto, o bloco __finally não é executado se você chamar qualquer uma das seguintes funções dentro do bloco __try: ExitProcess, ExitThread ou abort.
O bloco __finally é executado no contexto da função na qual o manipulador de terminação está localizado. Isso significa que o bloco __finally pode acessar as variáveis locais dessa função. A execução do bloco __finally pode terminar por qualquer um dos seguintes meios.
- Execução da última instrução no bloco e continuação para a próxima instrução
- Uso de uma instrução de controle (return, break, continue ou goto)
- Uso de longjmp ou um salto para um manipulador de exceção
Se a execução do bloco __try terminar devido a uma exceção que invoca o bloco de manipulação de exceções de um manipulador de exceções baseado em quadro, o bloco __finally será executado antes que o bloco de manipulação de exceções seja executado. Da mesma forma, uma chamada para a função de biblioteca de tempo de execução longjmp C do bloco __try causa a execução do bloco __finally antes que a execução seja retomada no destino da operação longjmp. Se __try execução do bloco for encerrada devido a uma instrução de controle (return, break, continue ou goto), o bloco __finally será executado.
A função AbnormalTermination pode ser usada dentro do bloco __finally para determinar se o bloco __try terminou sequencialmente — ou seja, se atingiu a chave de fechamento (}). Deixar o bloco __try devido a uma chamada para longjmp, um salto para um manipulador de exceção ou uma instrução return, break, continue ou goto é considerado um encerramento anormal. Observe que a falha ao encerrar sequencialmente faz com que o sistema pesquise todos os quadros de pilha na ordem inversa para determinar se algum manipulador de terminação deve ser chamado. Isso pode resultar em degradação do desempenho devido à execução de centenas de instruções.
Para evitar o término anormal do manipulador de terminação, a execução deve continuar até o final do bloco. Você também pode executar a instrução __leave . A declaração __leave permite a rescisão imediata do bloqueio de __try sem causar rescisão anormal e sua penalidade de desempenho. Verifique a documentação do compilador para determinar se a instrução __leave é suportada.
Se a execução do bloco __finally for encerrada devido à instrução de controle de retorno, ela será equivalente a um goto para a chave de fechamento na função de delimitação. Portanto, a função de fechamento retornará.