100 votes

Pourquoi la gestion des exceptions est-elle mauvaise?

Le langage Go de Google n'a pas d'exception en tant que choix de conception, et la renommée de Linus of Linux a appelé les exceptions merde. Pourquoi?

94voto

asveikau Points 16871

Exceptions le rendre très facile d'écrire du code dans lequel une exception levée briser d'invariants et de laisser des objets dans un état incohérent. Ils ont essentiellement la force de vous rappeler que la plupart de toutes les déclarations que vous faites peut potentiellement jeter, et de gérer cela correctement. Cela peut être difficile et contre-intuitif.

Considérer quelque chose comme ceci comme un exemple simple:

class Frobber
{
private:
    int m_NumberOfFrobs;
    FrobManager m_FrobManager;

public:

    void Frob()
    {
        m_NumberOfFrobs++;

        m_FrobManager.HandleFrob(new FrobObject());
    }
};

En supposant que l' FrobManager va delete le FrobObject, cela semble OK, à droite? Ou peut-être pas... Imaginez alors si FrobManager::HandleFrob() ou operator new déclenche une exception. Dans cet exemple, l'augmentation de la m_NumberOfFrobs ne pas obtenir restaurées. Ainsi, toute personne utilisant cette instance de Frobber va avoir, éventuellement, un objet endommagé.

Cet exemple peut sembler stupide (ok, j'ai eu de me dégourdir un peu, afin de construire un :-)), mais, à emporter, c'est que si un programmeur n'est pas de penser constamment des exceptions, et de faire en sorte que chaque permutation de l'etat se roula en arrière chaque fois qu'il y a des projections, des ennuis de cette façon.

Comme un exemple, vous pouvez penser ce que tu pense de mutex. À l'intérieur d'une section critique, vous pouvez compter sur plusieurs états pour s'assurer que les structures de données ne sont pas endommagés et que les autres threads ne peuvent pas voir votre des valeurs intermédiaires. Si un quelconque de ces déclarations de manière aléatoire ne fonctionne pas, vous vous retrouvez dans un monde de douleur. Maintenant, prenez loin de serrures et de simultanéité, et de penser au sujet de chaque méthode comme ça. Pensez à chaque méthode comme une opération de permutations sur l'état de l'objet, si vous voulez. Au début de votre appel de méthode, l'objet doit être propre à l'état, et à la fin il devrait également être un état propre. Entre les deux, la variable foo peut être incompatible avec bar, mais votre code finira par corriger cette situation. Quelles sont les exceptions veux dire, c'est que l'un quelconque de vos déclarations pouvez interrompre à tout moment. Le fardeau de la preuve est sur vous à chaque méthode pour obtenir la droite et faire reculer lorsque cela se produit, ou commander les opérations afin de ne jette pas l'effet de l'état de l'objet. Si vous vous trompez, (et il est facile de faire ce genre d'erreur), alors le visiteur finit par voir vos valeurs intermédiaires.

Des méthodes comme le RAII, qui les programmeurs en C++ amour de mentionner comme la solution ultime à ce problème, aller un long chemin pour se protéger contre cela. Mais ils ne sont pas une solution miracle. Il fera en sorte de vous libérer des ressources sur un lancer, mais n'est pas libre à vous de penser au sujet de la corruption de l'état de l'objet et les appelants de voir les valeurs intermédiaires. Donc, pour beaucoup de gens, il est plus facile de dire, par fiat de style de codage, pas d'exceptions. Si vous restreindre le type de code que vous écrivez, il est plus difficile d'introduire ces bugs. Si vous ne le faites pas, il est assez facile de faire une erreur.

Des livres entiers ont été écrits sur l'exception sûr de codage en C++. Beaucoup d'experts ont eu tort. Si c'est vraiment complexe et a de nombreuses nuances, peut-être que c'est un bon signe que vous devez ignorer cette fonctionnalité. :-)

53voto

Stephen C Points 255558

La raison n'Allez pas avoir des exceptions est expliqué dans le langage Go de conception de la FAQ:

Les Exceptions sont une histoire similaire. Un le nombre de créations d'exceptions ont été proposé, mais chacun ajoute significative de la complexité de la langue et au moment de l'exécution. De par leur nature, exceptions durée de fonctions et peut-être même goroutines; ils ont de nombreuses implications. Il est également des inquiétudes quant à l'effet qu'ils sur les bibliothèques. Ils sont, par définition, exceptionnel pourtant l'expérience avec d'autres langues que l'appui de leur montrer qu'ils ont profonde effet de la bibliothèque et de l'interface spécification. Il serait agréable d' trouver un design qui leur permet d'être vraiment exceptionnel, sans encourager l' les erreurs courantes à se transformer en spécial flux de contrôle exige que tous les programmeur pour compenser.

Comme les génériques, les exceptions restent un problème ouvert.

En d'autres termes, ils n'ont pas encore compris comment prendre en compte les exceptions à Aller dans une manière qui ils pensent est satisfaisante. Ils ne disent pas que des Exceptions sont mauvais en soi;

Mise à JOUR - Mai 2012

L'Aller les concepteurs ont maintenant grimpé vers le bas de la clôture. Leur FAQ maintenant, dit ceci:

Nous croyons que le couplage des exceptions à une structure de contrôle, comme dans le try-catch-finally idiome, les résultats en alambiqué code. Elle tend aussi à encourager les programmeurs de l'étiquette trop ordinaire des erreurs, comme ne pas ouvrir un fichier, comme exceptionnelles.

Aller prend une approche différente. Pour la plaine d'erreur de manipulation, Go multi-valeur renvoie le rendre facile pour signaler une erreur sans surcharger la valeur de retour. Canonique type d'erreur, couplé avec d'autres fonctions, rend la gestion des erreurs agréable, mais très différente de celle d'autres langues.

Aller a aussi un couple de fonctions intégrées pour le signal et de le récupérer à partir de véritablement des conditions exceptionnelles. Le mécanisme de récupération est exécuté uniquement dans le cadre d'une fonction de l'état d'être déchirée vers le bas après une erreur, ce qui est suffisant pour gérer la catastrophe mais ne nécessite pas de supplément de structures de contrôle et, lorsque bien utilisé, peut entraîner propre code de gestion d'erreur.

Voir le Reporter, la Panique, et de Récupérer de l'article pour plus de détails.

Donc, la réponse courte est qu'ils peuvent le faire différemment de l'utilisation de multi-valeur de retour. (Et ils ont une forme de gestion de l'exception de toute façon.)


... et Linus de Linux renommée a appelé les exceptions de la merde.

Si vous voulez savoir pourquoi Linus pense exceptions sont de la merde, la meilleure chose à faire est de regarder pour ses écrits sur le sujet. La seule chose que j'ai suivi jusqu'à maintenant est cette citation qui est incorporé dans un couple d'e-mails sur le C++:

"L'ensemble de la gestion des exceptions C++ chose est fondamentalement brisé. C'est surtout cassé pour les noyaux."

Vous remarquerez qu'il parle de C++ exceptions, en particulier, et pas des exceptions, en général. (Et les exceptions C++ n' ont apparemment quelques problèmes qui les rendent difficile à utiliser correctement.)

Ma conclusion est que Linus n'a pas appelé exceptions (en général) "merde" à tous!

32voto

Robert Harvey Points 103562

Les exceptions ne sont pas mauvaises en soi, mais si vous savez qu'elles vont se produire souvent, elles peuvent coûter cher en performances.

En règle générale, les exceptions doivent signaler des conditions exceptionnelles et vous ne devez pas les utiliser pour contrôler le déroulement du programme.

30voto

TrueWill Points 14855

Je suis en désaccord avec "seulement lancer des exceptions dans une situation exceptionnelle." Alors que généralement vrai, c'est trompeur. Les Exceptions sont pour erreur de conditions (des erreurs d'exécution).

Quelle que soit la langue que vous utilisez, prendre une copie de Cadre des lignes Directrices de Conception: les Conventions, les Idiomes et les Modèles Réutilisables .Bibliothèques NET (2e Édition). Le chapitre sur l'exception lancer est sans égal. Quelques citations de la première édition (de la 2e à mon travail):

  • NE PAS retourner les codes d'erreur.
  • Codes d'erreur peut être facilement ignorés, et sont souvent.
  • Les Exceptions sont le principal moyen d'erreurs de déclaration dans les cadres.
  • Une bonne règle de base est que si une méthode ne permet pas de faire ce que son nom l'indique, il devrait être considéré comme une méthode de niveau d'échec, ce qui entraîne une exception.
  • NE PAS utiliser les exceptions pour le flux normal de contrôle, si possible.

Il y a des pages de notes sur les avantages des exceptions (API cohérence, choix de l'emplacement de l'erreur de code de traitement, amélioration de la robustesse, etc.) Il y a une section sur le rendement qui comprend plusieurs modèles (Testeur-Doer, Essayez de l'Analyser).

Les Exceptions et la gestion des exceptions sont pas mauvais. Comme n'importe quel autre caractéristique, ils peuvent être utilisés à mauvais escient.

12voto

ddaa Points 19102

Du point de vue de golang, je ne crois pas avoir la gestion des exceptions garde le processus de compilation simple et sûr.

Du point de vue de Linus, je comprends que le code du noyau est TOUT au sujet de cas de coin. Il est donc logique de refuser des exceptions.

Les Exceptions font sens dans le code, c'est bien à la baisse de la tâche en cours sur le sol, et où le code a plus d'importance que la gestion des erreurs. Mais ils nécessitent la génération de code à partir du compilateur.

Par exemple, ils sont beaux en plus de haut niveau, l'utilisateur en face de code, tels que le web et de bureau le code de l'application.

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