Partager via


/EH (Modèle de gestion des exceptions)

Spécifie la prise en charge du modèle de gestion des exceptions générée par le compilateur. Les arguments spécifient s’il faut appliquer catch(...) la syntaxe aux exceptions C++ structurées et standard, siextern le code « C » est supposé être appliqué aux throw exceptions et s’il faut optimiser certaines noexcept vérifications.

Syntaxe

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

Arguments

a
Active le déroulement standard de la pile C++. Intercepte les exceptions C++ structurées (asynchrones) et standard (synchrones) lorsque vous utilisez catch(...) la syntaxe. /EHaremplace les arguments et /EHc les /EHs arguments.

s
Active le déroulement standard de la pile C++. Intercepte uniquement les exceptions C++ standard lorsque vous utilisez catch(...) la syntaxe. /EHc Sauf indication contraire, le compilateur suppose que les fonctions déclarées en tant que extern « C » peuvent throw être une exception C++.

c
Lorsqu’elle est utilisée avec /EHs, le compilateur part du principe que les fonctions déclarées comme extern « C » ne sont jamais throw une exception C++. Il n’a aucun effet lorsqu’il est utilisé avec /EHa (autrement dit, /EHca équivaut à /EHa). /EHc est ignoré si /EHs ou /EHa n’est pas spécifié.

r
Indique au compilateur de générer en permanence des vérifications d’arrêt au moment de l’exécution pour toutes les fonctions noexcept . Par défaut, les vérifications à l’exécution pour noexcept peuvent être optimisées, si le compilateur détermine que la fonction appelle uniquement des fonctions qui ne lèvent pas d’exceptions. Cette option offre une conformité C++ stricte au coût d’un code supplémentaire. /EHr est ignoré si /EHs ou /EHa n’est pas spécifié.

-
Efface l’argument d’option précédent. Par exemple, /EHsc- est interprété comme /EHs /EHc-, et est équivalent à /EHs.

/EH les arguments peuvent être spécifiés séparément ou combinés, dans n’importe quel ordre. Si plusieurs instances du même argument sont spécifiées, la dernière remplace toutes les instances antérieures. Par exemple, /EHr- /EHc /EHs est le même que /EHscr-, et /EHscr- /EHr a le même effet que /EHscr.

Notes

Comportement de gestion des exceptions par défaut

Le compilateur génère toujours du code qui prend en charge la gestion asynchrone des exceptions structurées (SEH). Par défaut (autrement dit, si aucun /EHsc, /EHsou /EHa option n’est spécifié), le compilateur prend en charge SEH les gestionnaires dans la clause C++ catch(...) native. Toutefois, il génère également du code qui ne prend en charge que partiellement les exceptions C++. Le code de déroulement d’exception par défaut ne détruit pas les objets C++ automatiques en dehors des try blocs qui sortent de l’étendue en raison d’une exception. Les fuites de ressources et le comportement non défini peuvent se produire lorsqu’une exception C++ est levée.

Gestion des exceptions C++ standard

Prise en charge complète du compilateur pour le modèle de gestion des exceptions C++ Standard qui déroulemente en toute sécurité les objets de pile requis /EHsc (recommandé), /EHsou /EHa.

Si vous utilisez /EHs ou /EHsc, vos catch(...) clauses ne sont pas catch des exceptions structurées asynchrones. Toutes les violations d’accès et les exceptions managées System.Exception ne sont pas prises en compte. Et, les objets dans l’étendue lorsqu’une exception asynchrone se produit ne sont pas détruits, même si le code gère l’exception asynchrone. Ce comportement est un argument pour laisser des exceptions structurées non gérées. Au lieu de cela, tenez compte de ces exceptions irrécupérables.

Lorsque vous utilisez /EHs ou /EHsc, le compilateur suppose que les exceptions ne peuvent se produire qu’à une throw instruction ou à un appel de fonction. Cette hypothèse permet au compilateur d’éliminer le code pour le suivi de la durée de vie de nombreux objets déwindables, ce qui peut réduire considérablement la taille du code. Si vous utilisez /EHa, votre image exécutable peut être plus grande et plus lente, car le compilateur n’optimise try pas les blocs de manière agressive. Il laisse également dans les filtres d’exceptions qui nettoient automatiquement les objets locaux, même si le compilateur ne voit pas de code pouvant throw être une exception C++.

Gestion des exceptions C++ structurées et standard

L’option /EHa du compilateur active le déroulement de la pile sécurisée pour les exceptions asynchrones et les exceptions C++. Il prend en charge la gestion des exceptions C++ standard et structurées à l’aide de la clause C++ catch(...) native. Pour implémenter SEH sans spécifier /EHa, vous pouvez utiliser la syntaxe et __finally la __try__exceptsyntaxe. Pour plus d’informations, consultez Gestion des exceptions structurées.

Important

La spécification et la tentative de gestion de /EHa toutes les exceptions à l’aide catch(...) peuvent être dangereuses. Dans la plupart des cas, les exceptions asynchrones sont irrécupérables et doivent être considérées comme telles. Si vous les interceptez sans les gérer, cela risque de provoquer une altération du processus et de générer des bogues difficiles à trouver et à résoudre.

Même si Windows et Visual C++ prennent en charge SEH, nous vous recommandons vivement d’utiliser la gestion des exceptions C++ standard ISO (/EHsc ou /EHs). Cela rend votre code plus portable et plus flexible. Il peut arriver que vous deviez utiliser SEH du code hérité ou pour des types particuliers de programmes. Il est nécessaire dans le code compilé pour prendre en charge le Common Language Runtime (/clrpar exemple). Pour plus d’informations, consultez Gestion des exceptions structurées.

Nous vous recommandons de ne jamais lier des fichiers objet compilés à l’aide /EHa de ceux compilés à l’aide /EHs ou /EHsc dans le même module exécutable. Si vous devez gérer une exception asynchrone à l’aide /EHa de n’importe où dans votre module, utilisez cette option /EHa pour compiler tout le code du module. Vous pouvez utiliser la syntaxe de gestion des exceptions structurées dans le même module que le code compilé à l’aide /EHsde . Toutefois, vous ne pouvez pas combiner la SEH syntaxe avec C++ try, throwet catch dans la même fonction.

Utilisez /EHa si vous souhaitez catch une exception levée par un autre élément qu’un throw. Cet exemple génère et intercepte une exception structurée :

// 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;
    }
}

Gestion des exceptions sous /clr

L’option /clr implique /EHa (autrement dit, /clr /EHa est redondante). Le compilateur génère une erreur si /EHs elle /EHsc est utilisée après /clr. Les optimisations n’affectent pas ce comportement. Lorsqu’une exception est interceptée, le compilateur appelle les destructeurs de classe pour tous les objets qui se trouvent dans la même étendue que l’exception. Si une exception n’est pas interceptée, ces destructeurs ne sont pas exécutés.

Pour plus d’informations sur les restrictions de gestion des exceptions, /clrconsultez _set_se_translator.

Vérifications des exceptions d’exécution

L’option /EHr force les vérifications d’arrêt du runtime dans toutes les fonctions qui ont un noexcept attribut. Par défaut, les vérifications du runtime peuvent être optimisées si le serveur principal du compilateur détermine qu’une fonction appelle uniquement des fonctions non levées . Les fonctions qui ne lèvent pas d’exceptions sont des fonctions qui ont un attribut spécifiant qu’aucune exception ne peut être levée. Elles incluent les fonctions marquées noexcept, throw(), __declspec(nothrow)et, quand /EHc elles sont spécifiées, extern "C" fonctions. Les fonctions qui ne lèvent pas d’exceptions incluent également les fonctions que le compilateur a identifiées par inspection comme des fonctions ne levant pas d’exceptions. Vous pouvez définir explicitement le comportement par défaut à l’aide /EHr-de .

Un attribut non levée n’est pas une garantie que les exceptions ne peuvent pas être levées par une fonction. Contrairement au comportement d’une noexcept fonction, le compilateur MSVC considère une exception levée par une fonction déclarée à l’aide throw(), __declspec(nothrow)ou extern "C" comme comportement non défini. Les fonctions qui utilisent ces trois attributs de déclaration n’appliquent pas les vérifications d’arrêt du runtime pour les exceptions. Vous pouvez utiliser l’option /EHr pour vous aider à identifier ce comportement non défini, en forçant le compilateur à générer des vérifications d’exécution pour les exceptions non gérées qui s’échappent d’une noexcept fonction.

Définir l’option dans Visual Studio ou par programmation

Pour définir cette option du compilateur dans l'environnement de développement Visual Studio

  1. Ouvrez la boîte de dialogue Pages de propriété du projet. Pour plus d’informations, consultez Définir le compilateur C++ et les propriétés de build dans Visual Studio.

  2. Sélectionnez Propriétés>de configuration C/C++>Génération de code.

  3. Modifiez la propriété Activation des exceptions C++ .

    Sinon, affectez à Activation des exceptions C++ la valeur Non, puis dans la page de propriétés Ligne de commande , dans la zone Options supplémentaires , ajoutez l'option de compilateur.

Pour définir cette option du compilateur par programmation

Voir aussi

Options du compilateur MSVC
Syntaxe de ligne de commande du compilateur MSVC
Gestion des erreurs et des exceptions
Spécifications d’exception (throw)
Structured Exception Handling (C/C++)