Blocs de terminaison SEH (C++)

De RAD Studio
Aller à : navigation, rechercher

Remonter à Exceptions structurées sous Win32 (C++)

Le modèle de gestion des exceptions structurées supporte un "bloc de terminaison" qui est exécuté même si la sortie s'effectue normalement d'un bloc protégé ou via une exception. Le compilateur C++Builder supporte cette opération en C avec la syntaxe suivante :

 __try {
     func();
 }
 __finally {
     // this happens whether func() raises an exception or not
 }

Les blocs de terminaison sont supportés par une extension C++ où vous pouvez gérer le nettoyage dans le bloc __finally :

 try {
     func();
 }
 __finally {
     // this happens whether func() raises an exception or not
 }

L'exemple suivant illustre les blocs de terminaison :

 /* Program results:
  An exception:
  Caught an exception.
  The __finally is executed too!
  No exception:
  No exception happened, but __finally still executes!
  */
 #include <stdio.h>
 #include <windows.h>
 
 int main() {
 	float e, f, g;
 	try {
 		f = 1.0;
 		g = 0.0;
 		try {
 			puts("An exception:");
 			e = f / g;
 		}
 		__except (EXCEPTION_EXECUTE_HANDLER) {
 			puts("Caught an exception.");
 		}
 	}
 	__finally {
 		puts("The __finally is executed too!");
 	}
 	try {
 		f = 1.0;
 		g = 2.0;
 		try {
 			puts("No exception:");
 			e = f / g;
 		}
 		__except (EXCEPTION_EXECUTE_HANDLER) {
 			puts("Caught an exception.");
 		}
 	}
 	__finally {
 		puts("No exception happened, but __finally still executes!");
 	}
 	return e;
 }

Le code C++ peut aussi gérer un "bloc de terminaison" en créant des objets locaux avec des destructeurs qui sont appelés au moment de la sortie de la portée. Puisque les exceptions structurées C++Builder supportent le nettoyage des destructeurs, cela fonctionne quel que soit le type de l'exception déclenchée.

Remarque : Un cas particulier concerne ce qui se produit quand une exception est déclenchée et qu'elle n'est jamais gérée par le programme. Pour une exception C++, le compilateur C++Builder appelle des destructeurs pour les objets locaux (non requis par la définition du langage), étant donné qu'aucun nettoyage de destructeur ne se produit avec une exception Win32 non gérée.

Remarque : Le C++ standard ne supporte pas les blocs finally. Par contre, il recourt à des destructeurs pour gérer la libération des ressources. Toutefois, lors de l'utilisation de la VCL, écrite en Delphi, les blocs finally constituent un outil important en raison de la façon dont les objets VCL doivent être alloués sur le tas.

Voir aussi