/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. /EHa
remplace 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
, /EHs
ou /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é), /EHs
ou /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
__except
syntaxe. 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 (/clr
par 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 /EHs
de . Toutefois, vous ne pouvez pas combiner la SEH syntaxe avec C++ try
, throw
et 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, /clr
consultez _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
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.
Sélectionnez Propriétés>de configuration C/C++>Génération de code.
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
- Consultez ExceptionHandling.
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++)