à propos des exceptions c ++. func () throw ()
Question
Je lis cette page http://www.cplusplus.com/doc/tutorial /exceptions.html il dit que si j'écris function () throw (); aucune exception ne peut être levée dans cette fonction. J'ai essayé dans msvc 2005 d'écrire throw (), throw (int), throw () et rien du tout. chacun a eu exactement les mêmes résultats. Rien. J'ai jeté int, char *, un autre type et tout a été capturé de la même manière. Il semble que le lancer ne l’affecte pas du tout. Que fait réellement function () throw ()?
La solution
Voir cet article pour plus de détails sur les spécifications des exceptions C ++ et l'implémentation de Microsoft:
Microsoft Visual C ++ 7.1 ignore les spécifications d’exception sauf si elles sont vides. Les spécifications d'exception vides sont équivalentes à
__ declspec (nothrow)
et peuvent aider le compilateur à réduire la taille du code.[...] S'il voit une spécification d'exception vide, il supposera que vous savez ce que vous faites et optimisera les mécanismes de gestion des exceptions. De toute façon, si votre fonction vous tente - eh bien, honte à vous. Utilisez cette fonctionnalité uniquement si vous êtes 100% positif, votre fonction ne lance pas et ne le sera jamais.
Autres conseils
Vous constatez que cette version de VC ++ n’imposait pas les exceptions de spécification. Je crois que cela a été documenté comme un écart par rapport à la norme.
Cependant, les spécifications d’exception ne sont généralement pas une bonne idée. Si un programme les viole dans une implémentation conforme aux normes (ce que VC ++ de VS 2005 n'était pas dans ce cas), le système est censé l'attraper. Cela signifie que la spécification n'est pas un indice d'optimisation du compilateur, mais oblige plutôt le compilateur à aller plus loin et produit parfois un code sous-optimal.
Voir la raison d'être de Boost pour expliquer pourquoi le très réputé Boost le projet n'utilise pas de spécifications d'exception. Il s’agit de Boost, qui est un enfant de l’affiche qui a fait des choses étranges et utiles avec des parties avancées du langage.
Citation de Examen pragmatique des spécifications des exceptions :
Compréhensions (mauvaises)
Le deuxième problème concerne sachant ce que vous recevez. Autant personnes notables, y compris les auteurs de la spécification d'exception Boost raisonnement, l'ont dit, les programmeurs ont tendance à utiliser l'exception spécifications comme si elles se comportaient la façon dont le programmeur aimerait, au lieu de la façon dont ils le font réellement se comporter.
Voici ce que beaucoup de gens pensent que les spécifications d'exception font:
Garantissez que les fonctions ne liront que les exceptions listées (éventuellement aucune).
Activer les optimisations du compilateur en fonction des connaissances répertoriées uniquement des exceptions (éventuellement aucune) seront jeté.
Les attentes ci-dessus sont, encore une fois, faussement près d'être correct.
Voir le lien pour plus de détails.
Lancer une exception ne suffit pas, vous avez besoin d'un bloc try {} catch ()
pour intercepter les exceptions. Si vous n'interceptez pas les exceptions, std :: terminate ()
est appelé et votre programme se ferme abruptement. Prenez le temps de vous rendre sur la this .
-
Pour servir de contrat entre une interface implémentée et un utilisateur d'interface - vous indiquez quelles exceptions peuvent être rejetées de votre méthode, certaines personnes considèrent que cela fait partie d'une interface. (contrat) Ala vérifié les exceptions en Java.
-
Pour signaler au compilateur qu'il peut appliquer certaines optimisations dans le cas où aucune exception ne peut être levée d'une méthode / procédure (la configuration du traitement des exceptions coûte quelque chose)
Le lancement d'une exception non spécifiée dans la clause throw () est une erreur. Toutefois, l'implémentation ne vous demandera à aucun moment de la vérifier . En fait, il n'est même pas possible de vérifier, car cela inclut toutes les exceptions possibles des sous-routines de vos appels de sous-routines. (éventuellement à partir d'autres modules) Cela n'est même pas possible dans un seul module, car cela se résume facilement à un problème bloquant:)