2009-06-24 15 views

Répondre

13

Le contenu de la chaîne est défini par l'implémentation, donc je suppose que la réponse est oui.

Editer: Bien sûr que. La norme dit:

virtual const char* what() const throw(); 
5 Returns: An implementation-defined NTBS. 

Il doit retourner une chaîne, pas seulement un pointeur. Et une chaîne ne peut pas être NULL. Comme d'autres l'ont fait remarquer, il est facile de dériver des exceptions dont le what() renvoie NULL, mais je ne suis pas sûr de savoir comment ces choses correspondent à la conformité aux normes. Certainement, si vous implémentez what() dans votre propre classe d'exception, je considérerais qu'il est très mauvais de lui permettre de retourner NULL.

Plus:

Pour une autre question d'adressage si what() peut retourner NULL, et similaires questions passionnantes, s'il vous plaît voir Extending the C++ Standard Library by inheritance?

+0

Mais si vous overwridde quoi et il est pris par seulement const std :: exception & puis il peut être NULL, donc probablement préférable de vérifier à droite? –

+0

Il est virtuel mais il est donc possible que les mauvais programmeurs le rendent NULL – JaredPar

+0

Intéressant. Maintenant, comme je sais que certaines personnes aiment implémenter quoi via une chaîne std :: string et la méthode c_str(), je dois demander - est ce que c_str() d'une chaîne std :: correctement construite peut renvoyer NULL? (Je demande parce que j'ai cette situation dans le code que je travaille avec et je veux savoir si je dois aller ajouter quelques TODOs ou pas). –

2

Bien sûr, il peut être NULL:

class myexception: public exception 
{ 
    virtual const char* what() const throw() 
    { 
    return NULL; 
    } 
} myex; 
+1

Il est possible de le faire ** dans la langue ** (c.-à-d. votre code sera compilé), mais ceci est interdit par la norme C++ - voir la réponse de Neil. IOW, ne faites pas cela, car le code d'autres personnes peut se fier à ce que vous ne faites pas. –

+0

Je ne pense pas que ce soit "hors-la-loi" - la norme spécifie le comportement de std :: exception :: quoi - il ne semble pas que les exigences de l'utilisateur soient dérivées de std :: exception. –

5

Si Quelqu'un a hérité de std :: exception et a remplacé ce qui doit retourner NULL, alors c'est possible. Malgré l'excellente trouvaille de Neil dans la norme, il pourrait être bon de vérifier la présence de NULL. Bien que les spécifications des classes enfant de l'état std :: exception ne doivent pas renvoyer une valeur NULL, rien dans votre compilateur ne va appliquer cela et le code ci-dessus sera toujours légal selon la langue.

Cela peut être une situation idéale pour utiliser un assert ...

assert(except.what() != NULL); 

ou

if (except.what() != NULL) 
{ 
     ... normal processing ... 
} 
else 
{ 
     assert(false); 
} 

parce que c'est un cas où quelque chose ne devrait probablement jamais arriver, et vous êtes en supposant qu'il ne devrait pas arriver, mais aimerait quand même savoir (en mode debug) que vos suppositions sont fausses. Ensuite, vous pouvez adresser votre hypothèse incorrecte ou adresser le code incorrect qui pourrait aller à l'encontre de votre hypothèse (assurez-vous que what() ne renvoie pas NULL).

+1

Il est possible ** dans la langue ** (c'est-à-dire que votre code sera compilé), mais cela est interdit par la norme C++ - voir la réponse de Neil. –

+0

Ouais, je ne suis pas sûr que ce n'est pas un comportement non défini si vous venez de renvoyer NULL. C'est violer ce qu'il spécifie pour quoi(). –

0

Comme beaucoup d'autres l'ont souligné, what()ne devrait pas un pointeur nul mais il le pourraient. Le temps d'exécution d'un test nul n'est encouru que dans le cas exceptionnel où, vraisemblablement, il est moins important. En tout cas, je recommande au moins d'utiliser un assert.

Si l'espace de code est également un problème, j'espère que le assert, vos tests, avis de code et autres AQ seront suffisamment complets pour repérer toute exception non conforme et fautive avant l'expédition.

Aussi, soyez prudent avec le code de gestion des exceptions qui peuvent se jeter (par exemple, comme d'autres l'ont noté, l'allocation de mémoire avec std::string lors du traitement d'une exception std::bad_alloc.)

+0

L'allocation de mémoire n'est pas une bonne idée lors du traitement de std :: bad_alloc. Pour les autres exceptions, il est inutile de ne pas utiliser std :: string. –

Questions connexes