Instruction try-except
L’instruction try-except
est une extension spécifique à Microsoft qui prend en charge la gestion des exceptions structurées dans les langages C et C++.
// . . .
__try {
// guarded code
}
__except ( /* filter expression */ ) {
// termination code
}
// . . .
Grammaire
try-except-statement
:
__try
compound-statement
__except (
expression
)
compound-statement
Notes
L’instruction try-except
est une extension Microsoft aux langages C et C++. Elle permet aux applications cibles de garder le contrôle quand des événements se produisent qui mettent normalement fin à l’exécution du programme. Ces événements sont appelés exceptions structurées ou plus brièvement exceptions. Le mécanisme qui traite ces exceptions est appelé gestion des exceptions structurées.
Pour obtenir des informations connexes, consultez Instruction try-finally.
Les exceptions peuvent être basées sur le matériel ou sur le logiciel. La gestion des exceptions structurées est utile même quand les applications ne peuvent pas récupérer complètement d’exceptions matérielles ou logicielles. La gestion des exceptions structurées permet d’afficher les informations des erreurs et d’intercepter l’état interne de l’application pour faciliter le diagnostic du problème. Elle est particulièrement utile pour les problèmes intermittents qui ne sont pas faciles à reproduire.
Remarque
La gestion structurée des exceptions fonctionne avec Win32 pour les fichiers sources C et C++. Cependant, elle n’est pas conçue spécifiquement pour C++. Vous pouvez vous assurer que votre code est plus portable en utilisant la gestion des exceptions C++. En outre, la gestion des exceptions C++ est plus souple, car elle permet de traiter des exceptions de tout type. Pour les programmes C++, nous vous recommandons d’utiliser la gestion des exceptions C++ native : les instructions try, catch et throw.
L’instruction composée après la clause __try
est le corps ou la section protégée. L’expression __except
est également appelée expression de filtre. Sa valeur détermine la façon dont l’exception est gérée. L'instruction composée après la clause __except
constitue le gestionnaire d'exceptions. Le gestionnaire spécifie un ensemble d’actions à effectuer si une exception est levée pendant l’exécution de la section du corps. L'exécution se déroule comme suit :
La section protégée est exécutée.
Si aucune exception ne se produit pendant l'exécution de la section protégée, l'exécution se poursuit à l'instruction située après la clause
__except
.Si une exception se produit pendant l’exécution de la section protégée ou dans une routine appelée par la section protégée, l’expression
__except
est évaluée. Il existe trois valeurs possibles :EXCEPTION_CONTINUE_EXECUTION
(-1) L’exception est ignorée. Poursuivre l'exécution au point où l'exception s'est produite.EXCEPTION_CONTINUE_SEARCH
(0) L’exception n’est pas reconnue. Poursuivre la recherche d’un gestionnaire dans la pile, en premier pour qu’il contienne des instructionstry-except
, puis pour les gestionnaires avec la priorité la plus élevée suivante.EXCEPTION_EXECUTE_HANDLER
(1) L’exception est reconnue. Transférer le contrôle au gestionnaire d’exceptions en exécutant l’instruction composée__except
, puis poursuivre l’exécution après le bloc__except
.
L’expression __except
est évaluée en tant qu’expression C. Elle est limitée à une seule valeur, l’opérateur d’expression conditionnelle ou à l’opérateur de virgule. Si un traitement plus étendu est requis, l'expression peut appeler une routine qui retourne l'une des trois valeurs répertoriées ci-dessus.
Chaque application peut avoir son propre gestionnaire d'exceptions.
Passer directement à une instruction __try
n’est pas une opération valide, mais quitter une telle instruction est par contre valide. Le gestionnaire d’exceptions n’est pas appelé s’il est mis fin à un processus pendant l’exécution d’une instruction try-except
.
Pour la compatibilité avec les versions précédentes, _try, _exceptet _leave sont des synonymes pour __try
, __except
et __leave
, sauf si l’option du compilateur /Za (Désactiver les extensions de langage) est spécifiée.
Le mot clé __leave
Le mot clé __leave
est valide seulement dans la section protégée d’une instruction try-except
, et son effet est de passer directement à la fin de la section protégée. L'exécution se poursuit à la première instruction située après le gestionnaire d'exceptions.
Une instruction goto
permet également de quitter la section protégée, et elle ne dégrade pas les performances comme elle le fait dans une instruction try-finally. La raison en est que le déroulement de la pile ne se produit pas. Cependant, nous vous recommandons d’utiliser le mot clé __leave
au lieu d’une instruction goto
. La raison en est que vous êtes moins susceptible de faire une erreur de programmation si la section protégée est longue ou complexe.
Fonctions intrinsèques de gestion des exceptions structurées
La gestion des exceptions structurées fournit deux fonctions intrinsèques qui peuvent être utilisées avec l’instruction try-except
: GetExceptionCode et GetExceptionInformation.
GetExceptionCode
retourne le code (un entier de 32 bits) de l’exception.
La fonction intrinsèque GetExceptionInformation
retourne un pointeur vers une structure EXCEPTION_POINTERS contenant des informations supplémentaires sur l’exception. Ce pointeur vous permet d'accéder à l'état de l'ordinateur qui existait au moment d'une exception matérielle. La structure est comme suit :
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
Les types de pointeur PEXCEPTION_RECORD
et PCONTEXT
sont définis dans le fichier include <winnt.h>, et _EXCEPTION_RECORD
et _CONTEXT
sont définis dans le fichier include <excpt.h>.
Vous pouvez utiliser GetExceptionCode
dans le gestionnaire d’exceptions. Cependant, vous pouvez utiliser GetExceptionInformation
seulement dans l’expression du filtre d’exceptions. Les informations vers lesquelles elle pointe sont généralement sur la pile et ne sont plus disponibles quand le contrôle est transféré au gestionnaire d’exceptions.
La fonction intrinsèque AbnormalTermination est disponible dans un gestionnaire de terminaisons. Elle retourne 0 si le corps de l’instruction try-finally se termine séquentiellement. Dans tous les autres cas, elle retourne 1.
<excpt.h> définit des noms alternatifs pour ces fonctions intrinsèques :
GetExceptionCode
équivaut à _exception_code
GetExceptionInformation
équivaut à _exception_info
AbnormalTermination
équivaut à _abnormal_termination
Exemple
// exceptions_try_except_Statement.cpp
// Example of try-except and try-finally statements
#include <stdio.h>
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
puts("in filter.");
if (code == EXCEPTION_ACCESS_VIOLATION)
{
puts("caught AV as expected.");
return EXCEPTION_EXECUTE_HANDLER;
}
else
{
puts("didn't catch AV, unexpected.");
return EXCEPTION_CONTINUE_SEARCH;
};
}
int main()
{
int* p = 0x00000000; // pointer to NULL
puts("hello");
__try
{
puts("in try");
__try
{
puts("in try");
*p = 13; // causes an access violation exception;
}
__finally
{
puts("in finally. termination: ");
puts(AbnormalTermination() ? "\tabnormal" : "\tnormal");
}
}
__except(filter(GetExceptionCode(), GetExceptionInformation()))
{
puts("in except");
}
puts("world");
}
Sortie
hello
in try
in try
in filter.
caught AV as expected.
in finally. termination:
abnormal
in except
world
Voir aussi
Écrire un gestionnaire d’exceptions
Structured Exception Handling (C/C++)
Mots clés
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour