/EH (Modelo de tratamento de exceção)

Especifica o suporte ao modelo de manipulação de exceção gerado pelo compilador. Os argumentos especificam se a sintaxe deve ser aplicada catch(...) a exceções C++ estruturadas e padrão, se extern o código "C" é considerado para throw exceções e se é possível otimizar a ausência de verificações específicas noexcept .

Syntax

/EHa[-]
/EHs[-]
/EHc[-]
/EHr[-]

Argumentos

a
Habilita o desenrolamento de pilha C++ padrão. O captura as exceções estruturadas (assíncronas) e C++ padrão (síncronas) quando você usa catch(...) a sintaxe. /EHa Substitui ambos os /EHs argumentos e /EHc .

s
Habilita o desenrolamento de pilha C++ padrão. Captura apenas exceções C++ padrão quando você usa catch(...) a sintaxe. A menos /EHc que também seja especificado, o compilador assume que as funções declaradas como extern "C" podem ser throw uma exceção de C++.

c
Quando usado com /EHs , o compilador assume que funções declaradas como extern "C" nunca throw são uma exceção de C++. Ele não tem efeito quando usado com /EHa (ou seja, /EHca é equivalente a /EHa ). /EHc será ignorado se /EHs ou /EHa não for especificado.

r
Informa ao compilador para sempre gerar verificações de término de tempo de execução para todas as noexcept funções. Por padrão, as verificações de tempo de noexcept execução podem ser otimizadas se o compilador determinar que as chamadas de função são apenas funções não throw ing. Essa opção fornece a conformidade do C++ estrita ao custo de algum código extra. /EHr será ignorado se /EHs ou /EHa não for especificado.

-
Limpa o argumento de opção anterior. Por exemplo, /EHsc- é interpretado como /EHs /EHc- e é equivalente a /EHs .

/EH os argumentos podem ser especificados separadamente ou combinados, em qualquer ordem. Se mais de uma instância do mesmo argumento for especificada, a última substituirá as anteriores. Por exemplo, /EHr- /EHc /EHs é o mesmo que /EHscr- e /EHscr- /EHr tem o mesmo efeito que /EHscr .

Comentários

Comportamento de tratamento de exceção padrão

O compilador sempre gera código que dá suporte ao tratamento de exceção estruturada assíncrona ( SEH ). Por padrão (ou seja, se nenhuma /EHsc opção, /EHs ou /EHa for especificada), o compilador oferece suporte SEH a manipuladores na cláusula C++ catch(...) nativa. No entanto, ele também gera código que dá suporte parcial apenas a exceções C++. O código de desenrolamento de exceção padrão não destrói objetos C++ automáticos fora dos try blocos que saem do escopo devido a uma exceção. Vazamentos de recursos e comportamento indefinido podem ocorrer quando uma exceção de C++ é throw n.

Manipulação de exceção padrão do C++

Suporte completo ao compilador para o modelo de manipulação de exceção C++ padrão que o desenrola com segurança de objetos de pilha requer /EHsc (recomendado), /EHs ou /EHa .

Se você usar /EHs ou /EHsc , suas catch(...) cláusulas não catch são exceções estruturadas assíncronas. Quaisquer violações de acesso e exceções gerenciadas System.Exception vão despercebidas. E, os objetos no escopo quando ocorre uma exceção assíncrona não são destruídos, mesmo que o código manipule a exceção assíncrona. Esse comportamento é um argumento para deixar exceções estruturadas sem tratamento. Em vez disso, considere essas exceções fatais.

Quando você usa /EHs o ou /EHsc o, o compilador supõe que as exceções só podem ocorrer em uma throw instrução ou em uma chamada de função. Essa suposição permite que o compilador elimine o código para acompanhar o tempo de vida de muitos objetos desenrolados, o que pode reduzir significativamente o tamanho do código. Se você usar /EHa o, a imagem executável poderá ser maior e mais lenta, pois o compilador não otimiza try os blocos de forma agressiva. Ele também deixa em filtros de exceção que limpam automaticamente os objetos locais, mesmo que o compilador não veja qualquer código que possa throw uma exceção de C++.

Manipulação de exceção C++ estruturada e Standard

A opção de compilador habilita o /EHa desenrolamento de pilha segura para exceções assíncronas e exceções de C++. Ele dá suporte ao tratamento de C++ padrão e de exceções estruturadas usando a cláusula C++ catch(...) nativa. Para implementar SEH sem especificar /EHa , você pode usar a __try sintaxe, __except e __finally . Para obter mais informações, consulte manipulação de exceção estruturada.

Importante

Especificar /EHa e try o ing para lidar com todas as exceções usando catch(...) o 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.

embora Windows e Visual C++ suporte SEH , é altamente recomendável que você use a manipulação de exceção do C++ padrão ISO ( /EHsc ou /EHs ). Ele torna seu código mais portátil e flexível. Ainda pode haver ocasiões em que você precisa usar SEH no código herdado ou em determinados tipos de programas. Ele é necessário no código compilado para dar suporte ao Common Language Runtime ( /clr ), por exemplo. Para obter mais informações, consulte manipulação de exceção estruturada.

Recomendamos que você nunca vincule arquivos de objeto compilados usando /EHa para aqueles compilados usando /EHs o ou /EHsc no mesmo módulo executável. Se você precisar manipular uma exceção assíncrona usando /EHa qualquer lugar em seu módulo, use /EHa para compilar todo o código no módulo. Você pode usar a sintaxe de manipulação de exceção estruturada no mesmo módulo que o código que é compilado usando /EHs o. No entanto, você não pode misturar a SEH sintaxe com C++ try , throw e catch na mesma função.

Use /EHa se você quiser catch uma exceção que seja gerada por algo diferente de a throw . Este exemplo gera e catch es 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;
    }
}

Tratamento de exceção sob/CLR

A /clr opção implica /EHa (ou seja, /clr /EHa é redundante). O compilador gerará um erro se /EHs ou /EHsc for usado após /clr . As otimizações não afetam esse comportamento. Quando uma exceção é detectada, o compilador invoca os destruidores de classe para todos os objetos que estão no mesmo escopo que a exceção. Se uma exceção não for detectada, esses destruidores não serão executados.

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

Verificações de exceção de tempo de execução

A /EHr opção força as verificações de término do tempo de execução em todas as funções que têm um noexcept atributo. Por padrão, as verificações de tempo de execução poderão ser otimizadas se o back-end do compilador determinar que uma função só chama funções não throw ing . throwFunções não ing são funções que têm um atributo que especifica que nenhuma exceção pode ser throw n. Eles incluem funções marcadas,, __declspec(nothrow) e, quando /EHc é especificado, extern "C"throw() funções. noexcept As funções não- throw ing também incluem qualquer que o compilador determinado seja não- throw ing por inspeção. Você pode definir explicitamente o comportamento padrão usando /EHr- .

Um atributo não- throw ing não é uma garantia de que as exceções não podem ser throw n por uma função. ao contrário do comportamento de uma noexcept função, o compilador de MSVC considera uma exceção throw n por uma função declarada usando throw() , __declspec(nothrow) ou extern "C" como um comportamento indefinido. As funções que usam esses três atributos de declaração não impõem verificações de término de tempo de execução para exceções. Você pode usar a /EHr opção para ajudá-lo a identificar esse comportamento indefinido, forçando o compilador a gerar verificações de tempo de execução para exceções sem tratamento que escapem uma noexcept função.

definir a opção em Visual Studio ou de forma programática

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, confira Definir as propriedades de build e do compilador do C++ no Visual Studio.

  2. Selecione Propriedades> de configuraçãogeração de códigoC/C++> .

  3. Modifique a propriedade Habilitar exceções C++ .

    Ou defina Habilitar exceções do C++ como nãoe, em seguida, na página de propriedades da 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

opções do compilador MSVC
MSVC sintaxe de linha de comando do compilador
Erros e tratamento de exceção
Especificações de exceção ( throw )
Tratamento de exceções estruturado (C/C++)