45 votes

Confusion entre std :: runtime_error et std :: logic_error

J'ai vu récemment que le coup de pouce program_options bibliothèque jette un logic_error si la ligne de commande d'entrée étaient non-analysables. Qui a contesté mes hypothèses sur logic_error vs runtime_error.

Je suppose que les erreurs de logique (logic_error et ses classes dérivées) ont été les problèmes résultant de défaillances internes à respecter le programme d'invariants, souvent sous la forme d'illégal des arguments à l'intérieur de l'API. En ce sens, ils sont largement équivalentes à faire VALOIR, mais destiné à être utilisé dans libéré de code (contrairement à l'ASSERTION qui ne sont pas habituellement compilées dans code publié.) Ils sont utiles dans les situations où il est impossible d'intégrer des composants logiciels distincts dans le debug/versions de test ou les conséquences d'un échec sont telles qu'il est important de donner à l'exécution de la rétroaction au sujet de la non valide invariant condition à l'utilisateur.

De même, j'ai pensé que runtime_errors résulte exclusivement à l'exécution des conditions hors du contrôle de la programmeur: erreurs d'e/S, entrée utilisateur non valide, etc.

Cependant, program_options est évidemment fortement (surtout?) utilisé comme un moyen de l'analyse d'entrée de l'utilisateur final, donc dans mon modèle mental, il ne devrait certainement jeter un runtime_error dans le cas de mauvaise saisie.

Où vais-je tort? Êtes-vous d'accord avec le coup de pouce modèle d'exception de frappe?

32voto

Jerry Coffin Points 237758

Dans ce cas, je pense (au moins pour l'essentiel) vous avez raison et c'est mal. La norme décrit logic_error que: "La classe logic_error définit le type d'objets jetés comme des exceptions pour signaler des erreurs sans doute détectable avant que le programme s'exécute, telles que les violations de la logique les conditions préalables ou les invariants de classe." Un argument de ligne de commande qui ne peut pas être analysée ne semble pas être adapté très bien.

En revanche, il décrit runtime_error que: "La classe runtime_error définit le type d'objets jetés comme des exceptions pour signaler des erreurs sans doute détectable uniquement lorsque le programme s'exécute." Ce qui semble être un meilleur ajustement.

9voto

Vladimir Prus Points 3169

Oh, c'est une vieille question, mais permettez-moi de les faire revivre. D'un pur point de vue, vous avez raison. program_options devrait jeter les classes dérivées à partir de runtime_error ou logic_error selon que l'erreur est une erreur d'exécution ou de logique. (Je n'ai pas de consulter le code de déterminer cette idée de classement pour les exceptions).

À partir d'un point de vue pratique, je n'ai pas encore vu le code C++ qui le rend utile des décisions basées sur de savoir si l'exception est logic_error ou runtime_error. Après tout, la seule raison pour laquelle vous avez jeter un logic_error par opposition à laisser faire valoir fichier si vous voulez essayer de récupérer quelque sorte, et ce n'est pas différent de récupération à partir d'une erreur d'exécution. Personnellement, je l'ai vue logic_error vs runtime_error de la même façon que checked exceptions en Java -- théoriquement sympa, mais pas utile dans la pratique. Ce qui signifie, que peut-être, je vais juste faire de l' program_options::error dérivent exception. C'est quand je vais trouver que les "temps libres" tout le monde en parle.

6voto

hkaiser Points 8097

L'actuel projet de C++0x Standard dit (article 19.2):

1) Dans le modèle d'erreur reflète dans ces classes (c'est à dire les types d'exception), les erreurs sont divisés en deux grandes catégories: les erreurs de logique et les erreurs d'exécution.

2) La caractéristique les erreurs de logique, c'est qu'ils sont dus des erreurs dans la logique interne de l' programme. En théorie, ils sont évitables.

3) En revanche, les erreurs d'exécution sont dues les événements au-delà de la portée de la programme. Ils ne peuvent pas être facilement prédit à l'avance.

Ensemble, avec les citations citées dans l'une des autres réponses, c'est ce qui explique pourquoi Boost.ProgramOptions jette un std::logic_error évitable erreurs causées par une "erreur sans doute détectable avant que le programme s'exécute'.

1voto

cdunn2001 Points 3597

L'utilisateur peut vérifier que le fichier existe, exécutez le programme, et tout à coup apprendre que le fichier a été supprimé. C'est pourquoi un problème d'e/S est toujours un runtime_error. Stateful problèmes sont runtime_errors, même si l'appelant pouvait avoir vérifié, depuis un autre thread pourrait causer le problème.

logic_error , c'est quand les arguments d'une fonction sont mauvais. C'est seulement pour les choses qui auraient pu être pris plus tôt avec plus de la vérification de type.

Ainsi, "fichier manquant" est un runtime_error, mais "mal formaté nom de fichier" est un logic_error.

Techniquement, une erreur de logique à l'intérieur d'une fonction est une logic_error trop, mais si vous êtes assez intelligent pour tester à l'intérieur de votre propre fonction, vous devez être assez intelligent pour l'empêcher en premier lieu.

0voto

Eonil Points 19404

OMI,

  • std::logic_error est jeté intentionnellement par une logique de programme utilisateur C ++. Prédit par un programme utilisateur.

  • std::runtime_error est lancé par un runtime C ++ (ou une partie centrale de la jauge…) pour abstraire les erreurs de niveau inférieur. Se produit simplement sans aucune intention sans implication d'aucun code utilisateur.

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