Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Você pode lidar com uma exceção saltando para o nível do manipulador de exceções ou continuando a execução. Em vez de usar o código do manipulador de exceções para manipular a exceção e cair, você pode usar uma expressão de filtro para limpar o problema. Então, retornando EXCEPTION_CONTINUE_EXECUTION (-1), você pode retomar o fluxo normal sem limpar a pilha.
Observação
Algumas exceções não podem ser mantidas. Se o filtro for avaliado para -1 para tal exceção, o sistema gerará uma nova exceção. Ao ligar RaiseExceptionpara o , você determina se a exceção continuará.
Por exemplo, o código a seguir usa uma chamada de função na expressão de filtro : Esta função lida com o problema e, em seguida, retorna -1 para retomar o fluxo normal de controle:
// exceptions_Writing_an_Exception_Filter.cpp
#include <windows.h>
int Eval_Exception(int);
int main() {
__try {
;
}
__except (Eval_Exception(GetExceptionCode())) {
;
}
}
void HandleOverflow() {
// Gracefully recover
}
int Eval_Exception(int n_except) {
if (
n_except != STATUS_INTEGER_OVERFLOW &&
n_except != STATUS_FLOAT_OVERFLOW
) {
// Pass on most exceptions
return EXCEPTION_CONTINUE_SEARCH;
}
// Execute some code to clean up problem
HandleOverflow();
return EXCEPTION_CONTINUE_EXECUTION;
}
É uma boa ideia usar uma chamada de função na expressão de filtro sempre que o filtro precisar fazer algo complexo. A avaliação da expressão provoca a execução da função, neste caso, Eval_Exception.
Observe o uso de GetExceptionCode para determinar a exceção. Esta função deve ser chamada dentro da expressão de filtro da __except instrução.
Eval_Exception não pode chamar GetExceptionCode, mas deve ter o código de exceção passado para ele.
Esse manipulador passa o controle para outro manipulador, a menos que a exceção seja um estouro de inteiro ou de ponto flutuante. Se for, o manipulador chama uma função (HandleOverflow é apenas um exemplo, não uma função de API) para tentar recuperar adequadamente da exceção. O __except bloco de instrução, que neste exemplo está vazio, nunca pode ser executado porque Eval_Exception nunca retorna EXCEPTION_EXECUTE_HANDLER (1).
Usar uma chamada de função é uma boa técnica de uso geral para lidar com expressões de filtro complexas. Dois outros recursos da linguagem C que são úteis são:
O operador condicional
O operador de vírgula
O operador condicional é frequentemente útil aqui. Ele pode ser usado para verificar um código de retorno específico e, em seguida, retornar um dos dois valores diferentes. Por exemplo, o filtro no código a seguir reconhece a exceção somente se a exceção for STATUS_INTEGER_OVERFLOW:
__except (GetExceptionCode() == STATUS_INTEGER_OVERFLOW ? 1 : 0)
O objetivo do operador condicional, neste caso, é principalmente fornecer clareza, porque o código a seguir produz os mesmos resultados:
__except (GetExceptionCode() == STATUS_INTEGER_OVERFLOW)
O operador condicional é mais útil em situações em que você pode querer que o filtro avalie para -1, EXCEPTION_CONTINUE_EXECUTION.
O operador de vírgula permite executar várias expressões em sequência. Em seguida, ele retorna o valor da última expressão. Por exemplo, o código a seguir armazena o código de exceção em uma variável e, em seguida, testa-o:
__except (nCode = GetExceptionCode(), nCode == STATUS_INTEGER_OVERFLOW)
Ver também
Escrevendo um manipulador de exceção
Tratamento de exceções estruturadas (C/C++)