2010-12-19 2 views
4

J'écris une bibliothèque C++ qui utilise une bibliothèque C externe tierce. Ainsi, ma bibliothèque appellera des fonctions dans cette bibliothèque tierce et la bibliothèque tierce rappellera dans une partie différente de ma bibliothèque. Je me demande ce qu'il advient des exceptions dans ce cas-ci? Dites MyLib :: foo() appelle la fonction de bibliothèque C externe qui appelle finalement MyLib :: bar(), et la barre lance une exception, que se passe-t-il? L'exception sera-t-elle correctement propagée à un gestionnaire dans foo()?propagation d'exception dans les bibliothèques C externes liées

Merci!

Répondre

6

L'exception sera-t-elle correctement propagée à un gestionnaire dans foo()?

Je pense que les exceptions propagées via le code C externe sont indéfinies. Ce qui est encore pire, le code C n'est pas préparé et incapable de gérer l'exception. Le code C n'a pas besoin d'être immunisé contre les retours soudains et inattendus, donc il ne connaît pas de RAII.

Lorsque j'ai été confronté à une telle situation, j'ai intercepté l'exception avant de retourner à l'API C, je l'ai stockée et relancé une fois l'appel est revenu de l'API C.

+2

C'est mieux que ma réponse. Je n'ai pas vu que la bibliothèque tierce était C plutôt que C++. Même si le questionneur mentionne cela plusieurs fois. L'heure du coucher, peut-être. –

+0

Ceci est la bonne réponse. Alors que certaines implémentations (GNU) se mettent en quatre pour essayer de permettre aux exceptions de se propager à travers le code C, c'est une très mauvaise idée de s'en servir. Non seulement il n'est pas portable, mais il n'y a aucune raison de supposer que le code C entre les deux n'aura pas d'état incohérent ou qu'il contiendra des allocations de mémoire qui n'ont pas encore été enregistrées en externe ou libérées. Au mieux, vous demandez des fuites de mémoire et, au pire, des plantages aléatoires. J'aime la suggestion de sbi sur la façon de contourner le problème, mais il vaut probablement mieux éviter de jeter des exceptions à travers les limites du module. –

+1

@Tommy: J'ai écrit une longue explication pourquoi laisser des exceptions se propager via un C lib est mauvais comme un commentaire à votre réponse et est devenu grincheux quand vous l'aviez déjà supprimé quand je voulais commettre le commentaire. Alors merci pour votre gentil commentaire, qui a compensé cela. ':)' – sbi

1

Il s'agit d'un détail de mise en œuvre de plate-forme lourde. En général, la plomberie d'exception est susceptible de pouvoir dérouler la pile à travers les trames d'activation de la fonction C. Nécessaire parce que le CRT est souvent écrit en C. Cependant, le code C est peu susceptible d'être heureux à ce sujet, l'état a muté qui ne peut pas être restauré. Juste au cas où il s'agit de Windows, le code C a une photo. Les exceptions C++ sont greffées sur le support d'exception générique intégré à Windows, appelé Structured Exception Handling (SEH). Vous utilisez les mots-clés __try et __except pour appeler un filtre d'exception qui peut restaurer l'état du code C. Évidemment, ce n'est pas portable.

Ne jamais poser une question de détail d'implémentation sans mentionner les détails d'implémentation, s'il vous plaît.

1

Lire (et acheter!) Herb Sutter C++ Coding Standards

# 62: Ne laissez pas les exceptions de se propager à travers les frontières du module.

Questions connexes