Partager via


/EH (Modèle de gestion des exceptions)

Spécifie le genre de gestion des exceptions à utiliser par le compilateur, et détruit les objets C++ qui sont hors de portée à la suite d'une exception. Si /EH n'est pas spécifié, le compilateur intercepte les exceptions structurées asynchrones et les exceptions C++, mais ne détruit pas les objets C++ qui sont hors de portée à la suite d'une exception asynchrone.

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

Arguments

  • a
    Modèle de gestion des exceptions qui intercepte les exceptions asynchrones (structurées) et synchrones (C++).

  • s
    Modèle de gestion des exceptions qui intercepte uniquement les exceptions C++ et qui indique au compilateur de supposer que les fonctions déclarées en tant que fonctions extern "C" peuvent lever une exception.

  • c
    S'il est utilisé avec s (/EHsc), ce modèle intercepte uniquement les exceptions C++ et indique au compilateur de supposer que les fonctions déclarées en tant que fonctions extern "C" ne lèvent jamais d'exception C++.

    /EHca équivaut à /EHa.

Notes

L'option de compilateur /EHa permet de prendre en charge la gestion des exceptions structurées asynchrones (SEH) avec la clause C++ native catch(...). Pour implémenter la gestion des exceptions structurées sans spécifier /EHa, vous pouvez utiliser la syntaxe __try, __except et __finally. Bien que Windows et Visual C++ prennent en charge la gestion des exceptions structurées, nous vous recommandons fortement d'utiliser la gestion des exceptions C++ normalisée par l'ISO (/EHs ou /EHsc), car elle rend le code plus portable et plus flexible. Cependant, pour du code existant ou pour certains genres de programme particuliers (par exemple, dans le code compilé pour prendre en charge le Common Language Runtime (/clr (Compilation pour le Common Language Runtime))), il vous faudra peut-être encore utiliser la gestion des exceptions structurées. Pour plus d'informations, consultez Gestion structurée des exceptions (C/C++).

Il peut s'avérer dangereux de spécifier /EHa et de tenter de gérer toutes les exceptions à l'aide de catch(...). 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.

Si vous utilisez /EHs ou /EHsc, votre clause catch(...) n'intercepte pas les exceptions structurées asynchrones. Les violations d'accès et les exceptions Exception non gérées ne sont pas interceptées. En outre, les objets contenus dans la portée lorsqu'une exception asynchrone est générée ne sont pas détruits même si l'exception asynchrone est gérée.

Si vous utilisez /EHa, l'image risque d'être plus grande et de ne pas être optimale, car le compilateur n'optimise pas un bloc try de manière aussi intensive. En outre, elle laisse les filtres d'exception qui appellent automatiquement les destructeurs de tous les objets locaux même si le compilateur ne voit pas de code susceptible de lever une exception C++. Cette approche permet un déroulement sécurisé de la pile pour les exceptions asynchrones, ainsi que pour les exceptions C++. Lorsque vous utilisez /EHs, le compilateur suppose que les exceptions ne peuvent se produire qu'au niveau d'une instruction throw ou d'un appel de fonction. Cela permet au compilateur d'éliminer le code de suivi de la durée de vie de nombreux objets non déroulables, ce qui peut entraîner une réduction considérable de la taille du code.

Nous vous recommandons de ne pas lier les objets compilés à l'aide de /EHa avec les objets compilés à l'aide de /EHs dans le même module exécutable. Si vous devez gérer une exception asynchrone à l'aide de /EHa dans votre module, utilisez /EHa pour compiler l'ensemble du code du module. Vous pouvez utiliser la syntaxe de gestion des exceptions structurées dans le même module que celui du code compilé à l'aide de /EHs. Toutefois, vous ne pouvez pas mélanger la syntaxe de gestion des exceptions structurées avec try, throw et catch dans la même fonction.

Utilisez /EHa si vous souhaitez intercepter une exception levée par autre chose que 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;
   }
}

L'option /EHc exige la spécification de /EHs ou /EHa. L'utilisation de /clr implique /EHa (en d'autres termes, /clr /EHa est redondant). Le compilateur génère une erreur si /EHs[c] est utilisé après /clr. Les optimisations n'affectent pas ce comportement. Lorsqu'une exception est interceptée, le compilateur appelle le ou les destructeurs de classe des objets compris dans la même portée que l'exception. Lorsqu'une exception n'est pas interceptée, ces destructeurs ne sont pas exécutés.

Pour plus d'informations sur les restrictions relatives à la gestion des exceptions sous /clr, consultez _set_se_translator.

Cette option peut être désactivée à l'aide du symbole -. Par exemple, /EHsc- est interprété en tant que /EHs /EHc- et équivaut à /EHs.

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 Comment : ouvrir les pages de propriétés d'un projet.

  2. Dans le volet gauche, développez 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

Référence

Options du compilateur

Définition des options du compilateur

Spécifications d'exception

Gestion structurée des exceptions (C/C++)

Concepts

Gestion des erreurs et des exceptions (Modern C++)