août
2008
Quel programmeur C++ ne s’est jamais posé des questions quand à l’utilisation des pointeurs nuls ? Faut-il utiliser NULL ou 0 ? Ou encore (void*)0 ? Depuis bientôt 30 ans, c’est un sujet à problème et la polémique l’entourant est grande. C’est pourquoi le comité ISO de normalisation du C++ a fait le choix de mettre en place un nouvel objet dans la prochaine norme (C++0x) : nullptr.
Un problème, à l’origine
Considérons le code suivant.
void f(char *);
// ... plus loin dans le code ...
f(0);
Quelle fonction est appellée ? f(int) ou f(char *) ? C’est f(int) qui sera toujours appelée, même si vous vouliez appeler l’autre, en passant donc un pointeur nul.
Comment appeler l’autre alors, lorsque l’on veut passer un pointeur nul ?
Il faut recourir à une conversion explicite.
f( (char*)0 );
Pas très intuitif ni agréable n’est-ce pas ?
On peut se demander si NULL ne résoud pas le problème, maintenant. Hélas non, car sur un compilateur qui respecte la norme, NULL a pour valeur 0… ni (void *)0 ni quoique ce soit d’aute, 0 simplement.
Ce qui entraine donc que :
f(NULL);
appellera f(int) encore une fois.
Il y a d’autres situations qui posent problème : toutes celles où l’on voudrait avoir un objet qui désigne un pointeur nul mais où l’on ne dispose que de la valeur littérale 0.
Beaucoup de suggestions et propositions ont été apportées mais il y a une solution dans la prochaine norme qui règlera ces problèmes : nullptr.
nullptr, la solution
nullptr est un mot-clé réservé du langage qui désigne une rvalue constante de type std::nullptr_t. L’implémentation du type en question est laissée à l’appréciation des compilateurs. On est toutefois sûr d’en disposer sur un compilateur qui implémente(ra) la norme C++0x.
Voici des exemples d’utilisation :
char *pc=nullptr; //OK
char c=nullptr; //error, type mismatch
int num=nullptr; //error, type mismatch
//pointers to members
int (A::*pmf)(char *)=nullptr; //OK
int A::*pmi=nullptr; //OK, pointer to data member
//comparisons
if (nullptr==0) //error, type mismatch
if (nullptr)//error, conversion to bool not allowed
if (pc==nullptr) //OK
tirés de cet article.
Enfin, notre problème de départ est facilement résolu. Si l’on veut appeler f(char*) en lui donnant un pointeur nul, il nous suffit d’écrire f(nullptr).
Voici donc un nouveau billet sur les nouveautés de C++0x. D’autres devraient suivre petit à petit.
Bonne lecture.
D’un autre côté, ce code donnera une erreur de compilation. Comme dans beaucoup de cas où le compilateur se retrouve face à un appel de fonction, pour lequel il dispose de 2 surcharges qui conviennent parfaitement, autant l’une que l’autre.
Tu souhaiterais quel comportement à la place ?
PS : chapeau pour avoir déterré ce billet
C’est plein de bonnes intentions.
Mais comme souvent avec C++ on ne fait que repousser le problème un petit peu plus loin.
void f(int *); <br />
void f(char *); <br />
// ... plus loin dans le code ... <br />
f(nullptr); <br />