Instruction try-except
L’instruction try-except
est une extension spécifique à Microsoft qui prend en charge la gestion structurée des exceptions 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++. Il permet aux applications cibles de contrôler quand des événements se produisent qui terminent normalement l’exécution du programme. Ces événements sont appelés exceptions structurées ou exceptions pour un court terme. Le mécanisme qui traite de ces exceptions est appelé gestion des exceptions structurées (SEH).
Pour plus d’informations, consultez l’instruction try-finally.
Les exceptions peuvent être basées sur du matériel ou logicielles. La gestion structurée des exceptions est utile même si les applications ne peuvent pas récupérer complètement à partir d’exceptions matérielles ou logicielles. SEH permet d’afficher des informations d’erreur et d’intercepter l’état interne de l’application pour aider à diagnostiquer le problème. Il 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++. Toutefois, il n’est pas spécifiquement conçu 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 : try, catch et throw instructions.
L’instruction composée après la __try
clause 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 les 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 les appels de 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érez le contrôle vers le gestionnaire d’exceptions en exécutant l’instruction__except
composée, puis continuez l’exécution après le__except
bloc.
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.
Il n’est pas valide de sauter dans une __try
instruction, mais valide pour sortir d’un. Le gestionnaire d’exceptions n’est pas appelé si un processus est arrêté au milieu de l’exécution d’une try-except
instruction.
Pour la compatibilité avec les versions précédentes, _try, _except et _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 __leave
mot clé est valide uniquement dans la section protégée d’une try-except
instruction, et son effet est de passer à 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 goto
instruction peut également sortir de la section protégée et ne dégrade pas les performances comme dans une instruction try-finally . Cela est dû au fait que le déroulement de la pile ne se produit pas. Toutefois, nous vous recommandons d’utiliser la __leave
mot clé plutôt qu’une goto
instruction. La raison est que vous êtes moins susceptible de faire une erreur de programmation si la section protégée est volumineuse ou complexe.
Fonctions intrinsèques de gestion des exceptions structurées
La gestion structurée des exceptions fournit deux fonctions intrinsèques qui sont disponibles pour être utilisées avec l’instruction try-except
: GetExceptionCode et GetExceptionInformation.
GetExceptionCode
retourne le code (entier 32 bits) de l’exception.
La fonction GetExceptionInformation
intrinsèque 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 PEXCEPTION_RECORD
de pointeur et PCONTEXT
sont définis dans le fichier <include winnt.h> et _CONTEXT
_EXCEPTION_RECORD
sont définis dans le fichier <include excpt.h>
Vous pouvez utiliser GetExceptionCode
dans le gestionnaire d’exceptions. Toutefois, vous ne pouvez utiliser GetExceptionInformation
que dans l’expression de filtre d’exception. Les informations qu’il pointe vers sont généralement sur la pile et ne sont plus disponibles lorsque le contrôle est transféré vers le gestionnaire d’exceptions.
La fonction intrinsèque AbnormalTermination est disponible dans un gestionnaire d’arrêt. 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 certains autres noms pour ces 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
Écriture d’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