8
votes

STD :: Exception en utilisant le message de l'objet local

est le code suivant lancer en toute sécurité une exception avec un message personnalisé? xxx pré>

avec VC ++ - 2008 Ceci donne: P>

exception: give me 5


0 commentaires

3 Réponses :


3
votes

Non, ce n'est pas en sécurité, car std :: exception n'a pas de constructeur prenant un caractère * dans la norme. Vous utilisez une extension MS. Pour le rendre portable et sûr, utilisez std :: runtime_error auquel vous pouvez passer un std :: string dans la CTOR.


3 commentaires

Merci d'avoir souligné std :: runtime_error , je vais l'utiliser à partir de maintenant. Je me demandais pourquoi je n'avais pas eu de problèmes jusqu'à présent avec les std :: exception détenant uniquement un pointeur de caractère (et non un std :: string ). Mais il semble que std :: crée sa propre copie du tableau de caractères.


C'est sûr, veuillez consulter les autres réponses à cette question. Être une extension ne le rend pas dangereux à utiliser juste non portable.


Peu de choses est dangereuse. Le passage à une version différente ou un compilateur différent pourrait provoquer la compilation de ce code mais invoquez un comportement non défini lors de la course. Puisqu'il y a des remplaçants portables qui font presque la même chose, pourquoi prendre des risques?



6
votes

C'est parfaitement sûr. Le constructeur qui prend une chaîne C en tant que paramètre unique fait une copie de la chaîne. Le constructeur qui prend une chaîne C et un paramètre de longueur vous permet de spécifier aucune mémoire ne doit être attribué et stocke un pointeur sur la chaîne (le paramètre de longueur est ignoré).

Notez que ces deux constructeurs sont des extensions à la classe std :: exception et ne sont pas standard. Sachez également que le constructeur qui prend une chaîne C en tant que paramètre unique n'est pas marqué comme explicite.



4
votes

C'est bon.

par §15.1 / 3: P>

lancer une exception Copy-Initialises (8.5, 12.8) un objet temporaire, appelé l'objet d'exception. P> blockQuote>

et §15.1 / 4: P>

La mémoire de l'objet d'exception est attribuée dans un non spécifié manière, sauf comme indiqué dans la version 3.7.4.1. Si un gestionnaire sort en retiré, Le contrôle est transmis à un autre gestionnaire pour la même exception. Les objet d'exception est détruit après le dernier actif restant Hangler pour l'exception sort par n'importe quel moyen d'autre que retirant ... p> blockQuote>

SO suite après expression de lancer code>: p>

L'expression em> sera copiée (nouvel objet sera créé par Copy Constructor) et vous Ne devrait pas s'inquiéter de l'objet local. p>

p>

sur le msg code> et const char * code> que vous vous inquiétez. .. voici l'implémentation de Microsoft:. p>

exception::exception(const char * const & _What)
: _Mywhat(NULL), _Mydofree(false)
{
   _Copy_str(_What);
 //^^^^^^^^^^^^^^^^^
}

void exception::_Copy_str(const char * _What)
{
   if (_What != NULL)
   {
      const size_t _Buf_size = strlen(_What) + 1;
      _Mywhat = static_cast<char *>(malloc(_Buf_size));
       if (_Mywhat != NULL)
       {
         _CRT_SECURE_STRCPY(const_cast<char *>(_Mywhat), _Buf_size, _What);
       //^^^^^^^^^^^^^^^^^^
         _Mydofree = true;
       }
   }
 }


2 commentaires

Je m'inquiétais par la version de std :: exception qui détient uniquement un pointeur de caractère. Mais il semble que le tableau de charcuterie sous-jacent soit copié par la contrainte.


@coProc: mis à jour pour vous mettre à l'aise.