Share via


/EH (modelo de tratamento de exceções)

Especifica o tipo de manipulação de exceção a ser usada pelo compilador e destrói os objetos C++ que saem do escopo como resultado de uma exceção. Se /EH não for especificado, o compilador captura exceções estruturadas assíncronas e exceções C++, mas não destrói os objetos de C++ que saem do escopo como resultado de uma exceção assíncrona.

/EH{s|a}[c][-]

Argumentos

  • a
    O modelo de tratamento de exceções que captura exceções assíncronas (estruturadas) e síncronas (C++).

  • s
    O modelo de tratamento de exceções que captura somente exceções C++ e diz ao compilador para assumir que as funções declaradas como extern "C" podem gerar um exceção.

  • c
    Se usado com s (/EHsc), captura as exceções C++ e diz ao compilador apenas para assumir que as funções declaradas como extern "C" nunca geram uma exceção C++.

    /EHca equivale a /EHa.

Comentários

A opção do compilador /EHa é usada para oferecer suporte ao tratamento de exceções estruturadas assíncronas (SEH) com a cláusula catch(...) C++ nativa. Para implementar SEH sem especificar /EHa, você pode usar __try, __except e a sintaxe __finally. Ainda que o Windows e o Visual C++ ofereçam suporte para SEH, recomendamos o uso do tratamento de exceções C++ padrão ISO (/EHs ou /EHsc), pois ele torna o código mais portátil e flexível. Entretanto, no código existente ou para tipos específicos de programas – por exemplo, no código compilado para oferecer suporte ao Common Language Runtime (/clr (compilação do Common Language Runtime)) — você ainda pode precisar usar o SEH. Para obter mais informações, consulte Tratamento de exceções estruturado (C/C++).

Especificar /EHa e tentar manipular todas as exceções usando catch(...) pode ser perigoso. Na maioria dos casos, as exceções assíncronas são irrecuperáveis e devem ser consideradas fatais. Capturá-las e continuar pode causar o corrompimento do processo e gerar bugs que são difíceis de localizar e corrigir.

Se você usar /EHs ou /EHsc, a cláusula catch(...) não capturará exceções estruturadas assíncronas. As violações de acesso e as exceções Exception gerenciadas não são capturadas, e os objetos no escopo quando uma exceção assíncrona é gerada não são destruídos ainda que a exceção assíncrona seja tratada.

Se você usar /EHa, a imagem poderá ser maior e não executar tão bem porque o compilador não otimiza um bloco try de forma tão radical e deixa filtros de exceção que chamam automaticamente os destruidores de todos os objetos locais ainda que o compilador não encontre código que possa gerar exceção C++. Isso permite a liberação segura da pilha para exceções assíncronas, bem como para exceções C++. Quando você usa /EHs, o compilador pressupõe que as exceções só podem acontecer em uma instrução throw ou em uma chamada de função. Isso permite que o compilador elimine o código para acompanhar o tempo de vida útil de muitos objetos liberáveis, e isso pode reduzir significativamente o tamanho de código.

É recomendável não vincular objetos compilados usando /EHa juntamente com os objetos compilados usando /EHs no mesmo módulo executável. Se você tiver de tratar uma exceção assíncrona usando /EHa em qualquer parte do módulo, use /EHa para compilar todo o código no módulo. Você pode usar a sintaxe de tratamento de exceções estruturadas no mesmo módulo do código que é compilado usando /EHs, mas não pode misturar a sintaxe SEH com try, throw e catch na mesma função.

Use /EHa se quiser capturar uma exceção que é gerada por algo diferente de throw. Este exemplo gera e captura uma exceção estruturada:

// compiler_options_EHA.cpp
// compile with: /EHa
#include <iostream>
#include <excpt.h>
using namespace std;

void fail() {   // generates SE and attempts to catch it using catch(...)
   try {
      int i = 0, j = 1;
      j /= i;   // This will throw a SE (divide by zero).
      printf("%d", j); 
   }
   catch(...) {   // catch block will only be executed under /EHa
      cout<<"Caught an exception in catch(...)."<<endl;
   }
}

int main() {
   __try {
      fail(); 
   }

   // __except will only catch an exception here
   __except(EXCEPTION_EXECUTE_HANDLER) {   
   // if the exception was not caught by the catch(...) inside fail()
      cout << "An exception was caught in __except." << endl;
   }
}

A opção /EHc requer que /EHs ou /EHa seja especificado. Usar /clr implica /EHa (isto é, /clr /EHa é redundante.) O compilador gera um erro se /EHs[c] for usado após /clr. As otimizações não afetam esse comportamento. Quando uma exceção é detectada, o compilador invoca o destruidor ou os destruidores de classe do objeto ou dos objetos que estão no mesmo escopo da exceção. Quando uma exceção não é detectada, esses destruidores não são executados.

Para obter informações sobre as restrições do tratamento de exceções em /clr, consulte _set_se_translator.

A opção pode ser limpa usando o símbolo -. Por exemplo, /EHsc- é interpretado como /EHs /EHc- e é equivalente a /EHs.

Para definir esta opção do compilador no ambiente de desenvolvimento do Visual Studio

  1. Abra a caixa de diálogo Páginas de Propriedades do projeto. Para obter detalhes, consulte Como abrir páginas de propriedade do projeto.

  2. No painel esquerdo, expanda Propriedades de Configuração, C/C++, Geração de Código.

  3. Modifique a propriedade de Habilita Exceções C++.

    Ou defina Habilita Exceções C++ como Não, e na página de propriedades de Linha de Comando, na caixa Opções Adicionais, adicione a opção do compilador.

Para definir essa opção do compilador via programação

Consulte também

Referência

Opções do compilador

Definindo opções do compilador

Especificações de exceção

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

Conceitos

Erros e tratamento de exceções (C++ moderno)