De retour à l'école il y a plus de 10 ans, ils vous apprenaient à utiliser des spécificateurs d'exception. Puisque je suis un des programmeurs C de Torvaldish qui évitent obstinément le C ++ sauf à y être contraint, je ne me retrouve que sporadiquement dans C ++, et j'utilise toujours des spécificateurs d'exception, car c'est ce que l'on m'a appris.
Cependant, la majorité des programmeurs C ++ semblent se désintéresser des spécificateurs d'exception. J'ai lu le débat et les arguments de divers gourous du C ++, comme ceux-ci . Autant que je sache, cela se résume à trois choses:
- Les spécificateurs d'exception utilisent un système de types incohérent avec le reste du langage ("système de types d'ombre").
- Si votre fonction avec un spécificateur d'exception renvoie autre chose que ce que vous avez spécifié, le programme sera arrêté de manière incorrecte et inattendue.
- Les spécificateurs d'exception seront supprimés dans la prochaine norme C ++.
Est-ce que je manque quelque chose ici ou sont-ce toutes les raisons?
Mes propres opinions:
En ce qui concerne 1): Et alors? C ++ est probablement le langage de programmation le plus incohérent jamais créé, en termes de syntaxe. Nous avons les macros, les goto / labels, la horde (comportement?) Du comportement indéfini / non spécifié / défini par l'implémentation, les types entiers mal définis, toutes les règles de promotion des types implicites, les mots clés de cas spéciaux tels que ami, auto , inscrivez-vous, explicite ... Et ainsi de suite. Quelqu'un pourrait probablement écrire plusieurs gros livres de toutes les bizarreries en C / C ++. Alors, pourquoi les gens réagissent-ils contre cette incohérence particulière, qui constitue un défaut mineur par rapport à de nombreuses autres caractéristiques beaucoup plus dangereuses de la langue?
Concernant 2): N'est-ce pas ma propre responsabilité? Il y a tellement d'autres façons de rédiger un bogue fatal en C ++, pourquoi ce cas particulier est-il pire? Au lieu d'écrire throw(int)
puis de lancer Crash_t, je peux aussi bien affirmer que ma fonction renvoie un pointeur sur int, puis créer un typecast sauvage et explicite et renvoyer un pointeur sur un Crash_t. L’esprit du C / C ++ a toujours été de laisser la plupart des responsabilités au programmeur.
Qu'en est-il des avantages alors? Le plus évident est que si votre fonction essaie de jeter explicitement un type différent de celui que vous avez spécifié, le compilateur vous donnera une erreur. Je crois que la norme est claire à ce sujet (?). Les bogues ne se produiront que lorsque votre fonction appellera d'autres fonctions qui jetteront le mauvais type.
Venant d’un monde de programmes C embarqués déterministes, je préférerais certainement savoir exactement quelle fonction me lancera. Si quelque chose dans le langage le supporte, pourquoi ne pas l'utiliser? Les alternatives semblent être:
void func() throw(Egg_t);
et
void func(); // This function throws an Egg_t
Je pense qu'il y a de grandes chances pour que l'appelant ignore / oublie de mettre en œuvre le test de capture dans le second cas, moins dans le premier cas.
Si je comprends bien, si l’une ou l’autre de ces deux formes décide de lever soudainement un autre type d’exception, le programme se bloquera. Dans le premier cas, parce qu'il n'est pas autorisé de lancer une autre exception, dans le second, parce que personne ne s'attendait à ce qu'il lance un SpanishInquisition_t et que, par conséquent, cette expression ne soit pas interceptée comme elle aurait dû l'être.
Dans ce dernier cas, avoir une capture de dernier recours (...) au plus haut niveau du programme ne semble pas vraiment mieux qu'un crash de programme: "Hé, quelque part dans votre programme, quelque chose a lancé une exception étrange et non gérée . ". Vous ne pouvez pas récupérer le programme une fois que vous êtes si éloigné de l'exception, la seule chose à faire est de quitter le programme.
Et du point de vue de l'utilisateur, ils se moquaient bien de recevoir une boîte de message malveillante de l'OS disant "Programme terminé. Blablabla à l'adresse 0x12345" ou une boîte de message maléfique de votre programme disant "Exception non gérée: myclass. func.something ". Le bug est toujours là.
Avec la prochaine norme C ++, je n'aurai d'autre choix que d'abandonner les spécificateurs d'exception. Mais je préférerais entendre des arguments solides sur la raison pour laquelle ils sont mauvais, plutôt que "Sa Sainteté l'a dit et c'est ainsi". Peut-être y at-il plus d’arguments contre eux que ceux que j’ai énumérés ou peut-être plus qu’ils ne le pensent?