42 votes

Pourquoi les exceptions en C ++ ne sont-elles pas vérifiées par le compilateur?

C++ fournit une syntaxe pour les exceptions, par exemple:

void G() throw(Exception);
void f() throw();

Cependant, le compilateur Visual C++ ne pas les vérifier, le lancer de drapeau est tout simplement ignoré. À mon avis, cela rend l'exception de la fonctionnalité inutilisable. Donc ma question est: est-il un moyen de rendre le compilateur de vérifier si les exceptions sont correctement pris/relancés? Par exemple, un Visual C++ plugin ou un autre compilateur C++.

PS. Je veux le compilateur de vérifier si les exceptions sont correctement pris, sinon vous vous retrouvez dans une situation où vous avez mis une capture autour de chaque appel de fonction que vous faites, même si elles déclarent explicitement qu'ils ne seront pas jeter quoi que ce soit.

Mise à jour: le compilateur Visual C++ ne afficher un avertissement lors de la jeter dans une fonction marquée avec throw(). C'est super, mais malheureusement, l'avertissement ne s'affiche pas lorsque vous appelez une routine qui pourrait lancer. Par exemple:

void f() throw(int) { throw int(13); }
void h() throw() { g(); } //no warning here!

39voto

rlbond Points 24215

Ce qui est drôle, c'est que Java a vérifié les exceptions, et les programmeurs Java haine de ceux qui sont trop.

Exception spécifications en C++ sont inutiles pour 3 raisons:

1. Des exceptions C++ spécifications inhiber l'optimisation.

À l'exception peut-être de lancer(), les compilateurs d'insérer du code supplémentaire pour vérifier que lorsque vous jetez une exception, elle correspond à la spécification d'exception de fonctions pendant une pile de vous détendre. Façon de rendre votre programme plus lent.

2. Des exceptions C++ spécifications ne sont pas de compilateur de l'exécution des

Aussi loin que votre compilateur est concernée, est syntaxiquement correct:

void AStupidFunction() throw()
{
    throw 42;
}

Ce qui est pire, rien d'utile advient-il si vous ne respectez pas une spécification d'exception. Votre programme se termine!

3. Des exceptions C++ spécifications font partie d'une fonction de signature.

Si vous avez une classe de base avec une fonction virtuelle et d'essayer de le remplacer, à l'exception des spécifications doivent correspondre exactement. Donc, vous feriez mieux de planifier à l'avance, et c'est toujours une douleur.

struct A
{
    virtual int value() const throw() {return 10;}
}

struct B : public A
{
    virtual int value() const {return functionThatCanThrow();} // ERROR!
}

Exception spécifications de vous donner ces problèmes, et le gain pour l'utilisation, est minime. En revanche, si vous évitez d'exception spécifications tout à fait, le codage est plus facile et vous éviter ce genre de choses.

31voto

Pieter Points 9200

Les spécifications d'exception sont assez inutiles en C ++.

Il n'est pas appliqué qu'aucune autre exception ne soit levée, mais simplement que la fonction globale unexpected() sera appelée (qui peut être définie)

L'utilisation de spécifications d'exception se résume principalement à vous induire en erreur (ou à vos pairs) dans un faux sentiment de sécurité. Mieux vaut tout simplement pas déranger.

15voto

Patrick Points 3893

Jetez un oeil à ceci:

http://www.gotw.ca/publications/mill22.htm

fondamentalement exception spécifications sont inapplicables ou inutilisables, mais cela ne fait pas d'exceptions près impraticable.

Quant à votre question, il n'y a aucun moyen d'obtenir le compilateur de vérifier que chaque type de levée est pris quelque part plus élevée dans le code, j'attends les unités de compilation font de ce difficile et il est impossible de le faire pour le code destiné à être utilisé dans une bibliothèque (où le haut niveau n'est pas disponible au moment de la compilation). Si vous voulez être certain que tout est pris puis coller un catch(...) tout en haut de votre code.

9voto

Thomas L Holaday Points 7165

Pour détecter préalablement à l'exécution des cas tels que ...

extern void f() throw (class Mystery);
void g() throw() { 
    f() ; 
}

... vous avez besoin d'une analyse statique. Oui, le compilateur est en train de faire beaucoup de l'analyse statique, mais parce que la norme est de "lever std::unexpected si le jet ne correspond pas," et il est parfaitement légal d'écrire une routine qui jette un objet qui ne correspond pas au rédacteur de devis, le compilateur exécutants ni avertir ni remarque.

Les outils d'analyse statique qui prétendent fournir des services d'alerte comprennent Gimpel Logiciel de peluches pour le C++ ...

1560 Uncaught exception 'Nom' ne pas jeter sur liste pour fonction de "Symbole"

et, selon cette réponse à une question, QA C++.

8voto

Tadeusz Kopec Points 7625

Parce que la norme le dit. La déclaration d'exception ne signifie pas qu'aucune autre exception ne sera levée. Cela signifie que si une exception non déclarée est levée, il sera appelé une fonction globale spéciale appelée inattendue () , qui par défaut termine le programme. Déclarer des exceptions dans les fonctions est généralement déconseillé (peut-être à l'exception d'une liste d'exceptions vide) car le comportement standard n'est pas très utile.

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