Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Gestion structurée des exceptions (SEH) est une extension Microsoft à C et C++ pour gérer avec panache certaines situations de code exceptionnelles, telles que les pannes matérielles. Bien que Windows et Microsoft C++ prennent en charge SEH, nous vous recommandons d’utiliser la gestion des exceptions C++ standard ISO dans le code C++. Cela rend votre code plus portable et plus flexible. Néanmoins, vous devrez peut-être encore utiliser SEH pour maintenir le code existant ou pour des types particuliers de programmes.
Section spécifique à Microsoft :
Grammaire
try-except-statement
:
__try
compound-statement
__except
(
filter-expression
)
compound-statement
try-finally-statement
:
__try
compound-statement
__finally
compound-statement
Notes
Avec SEH, vous pouvez garantir que les ressources telles que les blocs de mémoire et les fichiers seront publiées si l’exécution se termine de manière inattendue. Vous pouvez également gérer des problèmes spécifiques (par exemple, une mémoire insuffisante) en utilisant un code structuré concis qui ne repose pas sur les instructions goto
ni sur des tests élaborés de codes de retour.
Les instructions try-except
et try-finally
référencées dans cet article sont des extensions Microsoft des langages C et C++. Elles prennent en charge SEH en permettant aux applications de prendre le contrôle d'un programme après des événements qui termineraient sinon son exécution. Bien que la gestion SEH fonctionne avec des fichiers sources C++, elle n'est pas spécifiquement conçue pour C++. Si vous utilisez SEH dans un programme C++ que vous compilez en utilisant l’option /EHa
ou /EHsc
, des destructeurs d’objets locaux sont appelés, mais d’autres comportements d’exécution non prévus peuvent apparaître. Pour obtenir une illustration, consultez l’exemple présenté plus loin dans cet article. Dans la plupart des cas, au lieu de SEH, nous vous recommandons d’utiliser la gestion des exceptions C++ conforme à la norme ISO. En utilisant la gestion des exceptions C++, vous pouvez garantir que votre code est plus portable et gérer les exceptions de tout type.
Si vous avez du code C qui utilise SEH, vous pouvez le combiner avec du code C++ qui utilise la gestion des exceptions C++. Pour plus d’informations, consultez Gérer les exceptions structurées en C++.
Il existe deux mécanismes de gestion SEH :
Des gestionnaires d’exceptions, ou des blocs
__except
, qui peuvent répondre ou ignorer l’exception en fonction de la valeur defilter-expression
. Pour plus d’informations, consultez l’instructiontry-except
.Des gestionnaires d’arrêt, ou des blocs
__finally
, qui sont toujours appelés, qu’une exception provoque l’arrêt ou non. Pour plus d’informations, consultez l’instructiontry-finally
.
Ces deux types de gestionnaires sont distincts, mais étroitement liés via un processus appelé déroulement de la pile. Quand une exception structurée se produit, Windows cherche le gestionnaire d’exceptions le plus récemment installé qui est actif. Le gestionnaire peut effectuer l'une des trois opérations suivantes :
Il ne reconnaît pas l’exception et passe le contrôle à d’autres gestionnaires (
EXCEPTION_CONTINUE_SEARCH
).Il reconnaît l’exception, mais la fait disparaître (
EXCEPTION_CONTINUE_EXECUTION
).Il reconnaît l’exception et la gère (
EXCEPTION_EXECUTE_HANDLER
).
Le gestionnaire d'exceptions qui reconnaît l'exception peut ne pas être dans la fonction qui s'exécutait quand l'exception s'est produite. Il peut s’agir d’une fonction beaucoup plus élevée dans la pile. La fonction en cours d'exécution et toutes les autres fonctions sur le frame de pile sont terminées. Pendant ce processus, la pile est déroulée. Autrement dit, les variables locales non statiques des fonctions terminées sont effacées de la pile.
Tout en déroulant la pile, le système d'exploitation appelle tous les gestionnaires de terminaisons que vous avez écrits pour chaque fonction. En utilisant un gestionnaire de terminaisons, vous pouvez nettoyer les ressources qui autrement resteraient ouvertes en raison d’un achèvement anormal. Si vous entrez dans une section critique, vous pouvez la quitter via le gestionnaire de terminaisons. Lorsque le programme est en cours d’arrêt, vous pouvez effectuer d’autres tâches de gestion interne telles que la fermeture et la suppression des fichiers temporaires.
Étapes suivantes
Exemple
Comme indiqué précédemment, les destructeurs d’objets locaux sont appelés si vous utilisez SEH dans un programme C++ et que vous le compilez en utilisant l’option /EHa
ou /EHsc
. Toutefois, le comportement pendant l’exécution peut ne pas être celui prévu si vous utilisez également des exceptions C++. Cet exemple illustre ces différences de comportement.
#include <stdio.h>
#include <Windows.h>
#include <exception>
class TestClass
{
public:
~TestClass()
{
printf("Destroying TestClass!\n");
}
};
__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
printf("Throwing C++ exception\n");
throw std::exception("");
#else
printf("Triggering SEH exception\n");
volatile int *pInt = 0x00000000;
*pInt = 20;
#endif
}
__declspec(noinline) void TestExceptions()
{
TestClass d;
TestCPPEX();
}
int main()
{
__try
{
TestExceptions();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("Executing SEH __except block\n");
}
return 0;
}
Si vous utilisez /EHsc
pour compiler ce code, mais que la macro de contrôle de test local CPPEX
n’est pas définie, le destructeur TestClass
ne s’exécute pas. Une sortie classique ressemble à ceci :
Triggering SEH exception
Executing SEH __except block
Si vous utilisez /EHsc
pour compiler le code et que CPPEX
est défini à l’aide de /DCPPEX
(afin qu’une exception C++ soit levée), le destructeur de TestClass
s’exécute et la sortie ressemble à ceci :
Throwing C++ exception
Destroying TestClass!
Executing SEH __except block
Si vous utilisez /EHa
pour compiler le code, le destructeur TestClass
s’exécute si une exception a été levée à l’aide d’une expression throw
C++ standard ou à l’aide de SEH. Autrement dit, si CPPEX
est défini ou non. Une sortie classique ressemble à ceci :
Throwing C++ exception
Destroying TestClass!
Executing SEH __except block
Pour plus d’informations, consultez /EH
(Modèle de gestion des exceptions).
FIN de la section spécifique à Microsoft
Voir aussi
Traitement des exceptions
Mots clés
<exception>
Gestion des erreurs et des exceptions
Gestion structurée des exceptions (Windows)