229 votes

Jeter le mot clé en fonction ' signature s

Si la fonction ou une classe de méthode lève une exception, il est considéré comme une bonne pratique pour signifier cela dans la signature de la fonction ? Tenir compte :

Pourquoi est-ce que nous devrions faire cela ? Quels sont les avantages et les inconvénients d’un tel style de programmation ?

140voto

jalf Points 142628

Non, il n'est pas considéré comme une bonne pratique. Au contraire, il est généralement considéré comme une mauvaise idée.

http://www.gotw.ca/publications/mill22.htm va dans beaucoup plus de détails à propos de pourquoi, mais le problème est en partie le fait que le compilateur est incapable de faire appliquer, de sorte qu'il doit être vérifié au moment de l'exécution, qui est généralement indésirable. Et il n'est pas bien pris en charge dans tous les cas. (MSVC ignore exception des spécifications, à l'exception throw(), il interprète comme une garantie qu'aucune exception n'est levée.

65voto

sth Points 91594

Jalf.com déjà reliés, mais le GOTW met très bien pourquoi spécification d'exception ne sont pas aussi utiles qu'on pourrait l'espérer:

int Gunc() throw();    // will throw nothing (?)
int Hunc() throw(A,B); // can only throw A or B (?)

Les commentaires sont correctes? Pas tout à fait. Gunc() peut, en effet, de jeter quelque chose, et Hunc() peut bien jeter quelque chose autre que A ou B! Le compilateur juste garanties pour les battre absurde si elles ne... oh, et de battre votre programme insensé, la plupart du temps.

C'est exactement ce qu'il se résume, vous avez probablement juste va se retrouver avec un appel à l' terminate() et votre programme en train de mourir d'un rapide mais douloureuse de la mort.

Le GOTWs conclusion est la suivante:

Alors, voici ce qui semble être le meilleur conseil que nous en tant que communauté ont appris à compter d'aujourd'hui:

  • Morale n ° 1: ne Jamais écrire une spécification d'exception.
  • Morale n ° 2: l'Exception peut-être un vide, mais si j'étais vous, je voudrais éviter de même que.

14voto

Paolo Tedesco Points 22442

Le seul effet pratique du spécificateur de jet est que si quelque chose de myExc est émis par votre fonction, std::unexpected sera appelé (au lieu du mécanisme d'exception non géré normal).

Pour documenter le type d'exceptions qu'une fonction peut lancer, je le fais généralement:

 bool
some_func() /* throw (myExc) */ {
}
 

10voto

ps06756 Points 1851

Ainsi, alors que les recherches sur google à propos de ce lancer spécification, j'ai eu un coup d'oeil à cet article :- (http://blogs.msdn.com/b/larryosterman/archive/2006/03/22/558390.aspx)

Je suis en reprenant une partie de celui-ci ici aussi, de sorte qu'il peut être utilisé à l'avenir, indépendamment du fait que le lien ci-dessus fonctionne ou pas.

   class MyClass
   {
    size_t CalculateFoo()
    {
        :
        :
    };
    size_t MethodThatCannotThrow() throw()
    {
        return 100;
    };
    void ExampleMethod()
    {
        size_t foo, bar;
        try
        {
            foo = CalculateFoo();
            bar = foo * 100;
            MethodThatCannotThrow();
            printf("bar is %d", bar);
        }
        catch (...)
        {
        }
    }
};

Lorsque le compilateur voit ce, avec le "throw()" de l'attribut, le compilateur peut optimiser complètement le "bar" de la variable loin, parce qu'il sait qu'il n'existe aucun moyen pour la levée d'une exception de MethodThatCannotThrow(). Sans le lancer() attribut, le compilateur doit créer le "bar" de la variable, parce que si MethodThatCannotThrow lève une exception, le gestionnaire d'exception peut/dépendra de la valeur de la barre de variable.

En outre, l'analyse du code source des outils comme prefast peut être (et sera) utiliser le throw() annotation à améliorer leurs capacités de détection des erreurs - par exemple, si vous avez un try/catch et toutes les fonctions que vous appelez sont marqués comme throw(), vous n'avez pas besoin de le try/catch (oui, cela a un problème, si vous appelez une fonction qui pourrait jeter).

9voto

Greg D Points 24218

Lorsque les spécifications du jet ont été ajoutées à la langue, c'était avec les meilleures intentions, mais la pratique a confirmé une approche plus pratique.

Avec C ++, ma règle générale est d'utiliser uniquement les spécifications de jet pour indiquer qu'une méthode ne peut pas lancer. C'est une garantie forte. Sinon, supposons qu’elle puisse lancer n'importe quoi.

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