79 votes

Comment le runtime de gestion des exceptions C ++ est-il implémenté?

Je suis intrigué par le fonctionnement du mécanisme de gestion des exceptions C ++. Plus précisément, où est stocké l'objet exception et comment se propage-t-il à travers plusieurs portées jusqu'à ce qu'il soit capturé? Est-il stocké dans une zone globale?

Étant donné que cela pourrait être spécifique au compilateur, quelqu'un pourrait-il expliquer cela dans le contexte de la suite de compilateurs g ++?

43voto

MSalters Points 74024

Les mises en œuvre peuvent différer, mais il y a certaines des idées de base qui découlent de ces exigences.

L'exception de l'objet lui-même est un objet créé dans une fonction, détruit en l'appelant. Par conséquent, il est généralement impossible de créer l'objet sur la pile. D'autre part, de nombreux objets d'exception ne sont pas très grandes. Ergo, on peut créer des e.g 32 octets de la mémoire tampon et le débordement de tas si un plus grand objet exception est réellement nécessaire.

Comme pour le transfert de contrôle, deux stratégies existent. L'un est d'enregistrer assez d'informations dans la pile elle-même à se détendre de la pile. C'est en fait une liste de destructeurs de courir et de gestionnaires d'exceptions qui pourraient intercepter l'exception. Lorsqu'une exception se produit, exécutez l'arrière de la pile de l'exécution de ces destructeurs jusqu'à ce que vous trouver un correspondant de l'attraper.

La deuxième stratégie se déplace de cette information dans des tables à l'extérieur de la pile. Maintenant, lorsqu'une exception se produit, la pile d'appel est utilisé pour trouver les étendues qui sont entrés, mais pas quitté. Ceux-ci sont alors recherchés dans les tableaux statiques pour déterminer où la levée d'une exception seront traitées, et qui destructeurs de fonctionner entre. Cela signifie qu'il ya moins d'exception au-dessus sur la pile; des adresses de retour sont nécessaires de toute façon. Les tableaux sont données supplémentaires, mais le compilateur ne peut pas les mettre dans une demande chargés segment du programme.

18voto

Loki Astari Points 116129

Ceci est défini dans 15.1 Lancer une exception de la norme.

Le lancer crée un objet temporaire.
Comment la mémoire de cet objet temporaire est attribué n'est pas spécifié.

Après la création de l'objet temporaire le contrôle est passé à la plus proche de gestionnaire dans la pile d'appel. déroulement de la pile entre à lancer et à attraper point. Comme la pile est de se détendre tout pile les variables sont détruits dans l'ordre inverse de leur création.

À moins que l'exception est re-jetée temporaire est détruit à la fin de la gestionnaire d'où il a été pêché.

Remarque: Si vous attraper par de référence référence référence à la temporaire, Si vous l'attrapez par la valeur de l'objet temporaire est copié dans la valeur (et donc besoin d'un constructeur de copie).

Les conseils de S. Meyers (Capture par référence const).

try
{
    // do stuff
}
catch(MyException const& x)
{
}
catch(std::exception const& x)
{
}

12voto

Vous pouvez prendre un coup d'oeil ici pour une explication détaillée.

Il peut également aider à prendre un coup d'oeil à un truc dans la plaine, C de mettre en œuvre certaines de base de tri de la gestion des exceptions. Il s'agit d'utiliser setjmp() et longjmp() de la manière suivante: l'ancien sauve la pile dans l'ordre pour marquer le gestionnaire d'exception (comme "catch"), tandis que le second est utilisé pour "jeter" une valeur. La "levée" de la valeur est considérée comme si elle a été retourné par une fonction appelée. Le "bloc try" se termine lorsque setjmp() est appelée de nouveau ou lorsque la fonction retourne.

8voto

Jules Points 103

Je sais que c’est une vieille question, mais il y a une très bonne exposition, expliquant les deux méthodes utilisées dans chacune des gcc et VC ici : http://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X