7
votes

En C ++, est-il possible de forcer l'utilisateur à attraper des exceptions?

En bref, est-il possible d'obtenir C ++ forcer l'invocataire d'une méthode pour essayer ... Bloc de prise?

(Pour clarifier: Je ne veux pas nécessairement dire l'invocateur immédiat, je veux dire obliger le fait que c'est attrapé quelque part. En outre, je parle de forcer à la compilation.)

la longue:

J'ai lu que cela n'a pas été recommandé d'utiliser des spécifications d'exception et qu'il ne fonctionne pas correctement de toute façon ( http://4thmouse.com/mystuff/articles/usingExceptionSEffectivement.html )

Mais le consensus général semble favoriser l'utilisation d'exceptions pour renvoyer des erreurs sur l'utilisateur des méthodes d'écriture qui renvoient des codes d'erreur.

Donc, si j'écris dites une bibliothèque, qu'est-ce qui doit empêcher l'utilisateur de téléphoner à ma méthode sans m'essayer ... des blocs de capture, puis obtenir son programme s'écraser lorsque mon code jette une exception?

(Pour être clair, j'ai besoin que l'exception soit prise quelque part dans la pile d'utilisateurs, pas nécessairement dans le code d'appel immédiat, et le compilateur se plaindre si ce n'est pas le cas.)


10 commentaires

rien. C'est pourquoi il y a des exceptions. Vous pouvez choisir de les attraper ou de les laisser ruisseler "à l'étage". Si rien ne les attrape du tout, le système d'exploitation l'attrape et votre application s'arrête.


Lorsque vous lisez «Consensus général», pensez-y comme «la loi». Les bibliothèques qui renvoient des codes d'erreur plutôt que des exceptions sont une vraie corvée à travailler avec. :)


La question est de savoir pourquoi vous souciez-vous? C'est leur programme qui se bloque, et c'est donc leur problème .


@Angew, imaginez que nous et eux sont collectivement responsables d'un projet. :-)


@Marcb Mon problème est que le système d'exploitation les attrape au moment de l'exécution, par opposition au compilateur les attrapant lors de la compilation, comme dans une certaine langue qui commence avec J.


@nappyFalCon: Vous voulez dire cette langue où tout le monde déteste à l'aide de spécifications d'exception, car ils doivent utiliser des spécifications d'exception?


Oui, il y a un mécanisme appelé "examen de code".


Comment le compilateur peut-il attraper une exception de temps d'exécution? par exemple. "Fichier introuvable" n'est pas quelque chose que vous pouvez tester une fois et plus jamais.


@nappyFalcon: Si vous voulez dire Java, alors non, en Java, le compilateur n'atteint pas d'exceptions. Java soutient une erreur erronée appelée "exceptions vérifiées". Cette fonctionnalité ne nécessite toutefois pas l'appelant pour attraper quoi que ce soit. Il peut simplement ajouter l'exception à ses propres spécifications d'exception et être effectuée avec elle.


Je me souviens de cette notion - l'a vu très souvent: "N'utilisez pas mon logiciel de manière à ce que je ne m'attendais pas!"


3 Réponses :


10
votes

Non, ce n'est pas.

En effet, il n'y a pas de mécanisme pour forcer l'appelant d'une fonction (n'importe où dans la pile d'appels) pour gérer tout type d'erreur. Au moins, pas via une défaillance de la compilation. Les valeurs de retour peuvent être supprimées. Même grouper les codes d'erreur avec des valeurs de retour (via attendu ) ne délivrait pas une erreur de compilation si l'utilisateur ne vérifie pas si la valeur est disponible avant la récupération .

C ++ 17 peut nous donner l'attribut [[nodiscard]] , qui permet aux compilateurs de délivrer un avertissement si une valeur de retour (probablement un code d'erreur) est supprimée par l'appelant. Mais un avertissement du temps de compilation sera aussi proche que possible.


7 commentaires

WRT votre dernier point, désolé, je voulais dire, puis-je forcer l'utilisateur à l'attraper quelque part dans leur pile? Je vais mettre à jour la question.


@nappyFalcon Mettez-le dans la documentation selon laquelle votre interface de bibliothèque lancera des exceptions. C'est tout ce que j'attendrais. Je mettais normalement un attrape (std :: excepte const & e) et un attrape (...) avec la journalisation rond principale ()


@nappyFalcon: appelant immédiat ou appelant éventuel, cela ne change rien de la réponse.


Si les clients ont vraiment l'intention d'ignorer les erreurs, ils trouveront des moyens de le faire. Soyez-lui un bloc de capture vide ou int inutilisé_result = f (); .


@Christianhackl: Mieux vaut utiliser auto _ = f (); . Moins de taper et ça marche pour n'importe quoi.


@Nicolbolas c'est ce que j'ai peur de ... :-(


@nappyFalcon: Vous ne pouvez pas contrôler les autres personnes. [[nodiscard]] est utile, mais si les gens veulent ignorer son utilité, il n'y a rien que vous puissiez faire pour les arrêter. Faites de votre mieux, et laissez le mauvais code faire quel fait le mauvais code.



0
votes

Il y a un consensus général? Pas que je sois au courant. Quant aux exceptions, non. Le compilateur ne peut pas appliquer que quelqu'un attrape l'exception dans la pile d'appels. Au moment de la compilation, le compilateur n'a aucune idée qui peut appeler votre fonction et que votre fonction peut lancer une exception arbitraire, de même que toute fonction que votre fonction appelle. La liaison aurait peut-être une chance, mais il faudrait conserver beaucoup d'informations supplémentaires sur les exceptions sur les exceptions qu'une fonction peut lancer, ainsi que quelles exceptions une fonction peut attraper. Cela devient encore plus laids lorsque vous commencez à parler de bibliothèques chargées de manière dynamique (DLL / .SO) car cela devrait être résolu au moment de l'exécution.


0 commentaires

1
votes

En bref, est-il possible d'obtenir C ++ forcer l'invocataire d'une méthode Mettre un essai ... Bloc de capture?

non. Cela vaincrait tout le but des exceptions. Des exceptions sont spécifiquement conçues pour le cas d'utilisation de propagation des erreurs sur plusieurs couches sans que les couches intermédiaires ne soient au courant.

Disons que vous avez une hiérarchie d'appel comme A -> B - > C -> D -> E et une erreur se produit dans E. A peut gérer l'erreur. B, c et d n'ont pas besoin d'être conscients de l'erreur du tout. C'est exactement quelles exceptions sont bonnes pour!

Si vous souhaitez renvoyer une erreur directement à l'appelant car la gestion de l'erreur est en effet la préoccupation de l'appelant, une exception est souvent la mauvaise conception et une valeur de retour pourraient Soyez le meilleur choix.


"imposé" des exceptions "appliquées" d'une certaine forme ont été jugés en Java, mais je considérerais comme une expérience échouée, car elle entraîne généralement du code comme celui-ci: xxx

que c ++ n'encourage pas cela devrait être considéré comme une caractéristique .


J'ai lu qu'il n'a pas été recommandé d'utiliser des spécifications d'exception et que cela ne fonctionne pas correctement de toute façon

Exactement. La seule spécification d'exception qui a toujours été utile et qui a fonctionné était jet () pour signaler qu'aucune exception n'est lancée et que l'une a été remplacée dans C ++ 11 par noexcept .

Mais le consensus général semble favoriser l'utilisation d'exceptions à Erreurs de retour sur l'utilisateur des méthodes d'écriture qui renvoient une erreur Codes.

Voir ci-dessus. Cela dépend de si vous voulez une erreur de propager ou si l'appelant peut et doit le gérer.

Donc, si j'écris dis une bibliothèque, qu'est-ce que l'utilisateur d'appeler ma méthode sans essayer d'essayer ... des blocs de capture, puis d'obtenir son Programme Crashing lorsque mon code jette une exception?

une bibliothèque qui oblige son utilisateur à entourer tous les appels de fonction avec Essayez Les blocs ont une mauvaise interface et doivent être repensés, en conséquence.

aussi ... Vous supposez qu'un "programme" utilisera votre bibliothèque. Mais cette hypothèse ne sera pas toujours vraie. Le client de la bibliothèque peut lui-même une bibliothèque. Il peut y avoir beaucoup de couches de bibliothèque différentes entre le programme et votre bibliothèque. Vous utilisez des exceptions si vous ne vous souciez pas de la couche qui les gère.


0 commentaires