12
votes

Éviter l'initialisation de STD incorrect STD :: String String avec NULL Const Char * en utilisant g ++

A Y a-t-il des options G ++ pouvant détecter une initialisation inappropriée de STD :: String avec NULL Const Char *?

J'étais en train de transformer des champs Int dans STD :: Chaînes, c'est-à-dire: P>

struct Foo
{
   std::string id;
   Foo() : id(0) {} //oooops!
};


4 commentaires

Malheureusement, 0 est la seule valeur qui ne déclenchera pas une erreur pour une conversion invalide de Int vers le pointeur. Pour bien sûr, 0 est une constante de pointeur NULL, donc convertible à n'importe quel type de pointeur. Je ne sais rien de ce que vous puissiez faire autre que, comme le dit le visiteur, n'écrivez pas cet initialisateur en premier lieu.


La solution appropriée aurait été d'ajouter un constructeur privé std :: string :: string (int); . Ce serait une meilleure correspondance et provoquerait donc une erreur de compilation.


Je ne sais pas si vous vouliez dire cela de cette façon, mais cela pourrait réellement fonctionner, comme un test unique pour attraper les erreurs résultant de ce cycle de modifications de int à chaîne . Modifier std :: basique_string dans les en-têtes standard de g ++, vérifiez que le nouveau code compile, puis le modifier rapidement, avant que quiconque a notifié.


Oh, aucun changement d'en-têtes standard n'est pas une option :) Mais je devrais probablement demander à G ++ Devs d'ajouter le constructeur Int privé à l'avenir?


3 Réponses :


5
votes

Je pense que c'est en fait un comportement indéfini et non vérifié par le compilateur. Vous avez de la chance que cette implémentation jette une exception.

Toutefois, vous pouvez éviter de tels problèmes en précisant que vous souhaitez une initialisation par défaut ou zéro-initialisation sous une manière de type-agnostique: p>

struct Foo
{
   X id;
   Foo() : id() {} //note empty parenthesis
};


2 commentaires

Hm ... Vous dites donc votre constructeur par défaut pour INT Type Attributs 0?


Cette syntaxe signifie une initialisation zéro pour les types intégrés.



2
votes

Il y a une infrastructure dans GCC pour produire exactement ce type d'avertissement: xxx

lors de la compilation avec -wnonnull (qui est impliqué par -wall < / code>) produit: xxx

donc en principe, vous devez être en mesure de modifier l'en-tête du système correspondant (ou mieux pour expérimenter, modifier votre propre maison / bits / de base_string.h copie puis remplacez le système un avec -isystem $ home ) de la même manière: xxx

Cependant, cela ne aide pas parce que (au moins Dans 4.0.1) -Wnonnull n'est pas pris en charge en C ++ et l'attribut est apparemment ignoré. Ce n'est pas évident pourquoi c'est le cas; Peut-être a-t-il eu l'impression d'avoir mal interagi avec une surcharge ou quelque chose.


1 commentaires

En fait, votre basic_string CTOR __ attribut __ ((non null (1))) Cochons ci-dessus que le pointeur CE n'est pas null ; Il suffit de passer à __ attribut __ ((non null (2))) pour vérifier que __ s n'est pas null; Voir GCC.GNOU.ORG/ML/GCC/2006-04/MSG00549 .html



8
votes

Je ne peux pas penser à un moyen de détecter cela au moment de la compilation, j'ai donc écrit une fonction de constructeur à chaîne qui traite correctement avec Null Pointers: xxx

Je l'utilise chaque fois que je crée une chaîne et il y a une chance que l'entrée pourrait être nulle.


0 commentaires