Déroulement des exceptions (C++)
Remonter à Gestion des exceptions C++ standard
Quand une exception est déclenchée, la bibliothèque d'exécution prend l'objet déclenché, obtient le type de l'objet et recherche vers le haut dans la pile d'appels un gestionnaire dont le type correspond au type de l'objet déclenché. Dès qu'un gestionnaire est trouvé, la RTL déroule la pile jusqu'au point du gestionnaire, puis exécute le gestionnaire.
Dans le processus de déroulement, la RTL appelle les destructeurs de tous les objets locaux dans les cadres de pile entre le point où l'exception a été déclenchée et celui où elle a été interceptée. Si un destructeur provoque le déclenchement d'une exception lors du déroulement de la pile et qu'il ne la gère pas, la fonction terminate est appelée. Les destructeurs sont appelés par défaut, mais ce mode de fonctionnement peut être inhibé en utilisant l’option de compilation -xd
.
Remarque : Durant le processus de déroulement, la RTL n'appelle pas les destructeurs des objets alloués sur le tas plutôt que sur la pile. De ce fait, par exemple, les applications VCL utilisent des blocs finally pour que les objets VCL, qui sont toujours alloués sur le tas, soient correctement libérés. L'utilisation de pointeurs sécurisés constitue la seule exception à cette règle.
Utilisation de wrappers RAII pour supprimer automatiquement les pointeurs
Si des variables locales sont des pointeurs sur des objets et si une exception est déclenchée, ces pointeurs ne sont pas automatiquement supprimés. Ceci est dû au fait que le compilateur ne peut pas faire la différence entre un pointeur sur des données qui ont été allouées à cette fonction uniquement et un autre pointeur. Pour vous assurer que des objets alloués à une utilisation locale sont détruits dans le cas d'une exception, utilisez la classe unique_ptr
. Dans certains cas, la mémoire est libérée pour un pointeur alloué dans une fonction :
std::unique_ptr<TMyObject> obj(new TMyObject());
Dans cet exemple, si le constructeur de TMyObject
déclenche une exception, le pointeur sur l'objet alloué à obj
sera alors supprimé par la RTL quand elle déroule l'exception. C'est le seul cas où le compilateur supprime automatiquement une valeur de pointeur.
Remarque :
unique_ptr
est un template de classe qui est similaire àauto_ptr
, mais fournit une meilleure solution (auto_ptr
est obsolète).