En premier lieu, pour être 100% clair, il n'y a aucune différence entre C et C++ ici. Et deuxièmement, la question Stack Overflow que vous citez ne parle pas des pointeurs nuls; elle introduit des pointeurs non valides; des pointeurs qui, du moins selon le standard, provoquent un comportement indéfini juste en essayant de les comparer. Il n'y a pas moyen de tester en général si un pointeur est valide.
En fin de compte, il existe trois façons courantes de vérifier un pointeur nul :
if ( p != NULL ) ...
if ( p != 0 ) ...
if ( p ) ...
Tous fonctionnent, peu importe la représentation d'un pointeur nul sur la machine. Et tous, d'une manière ou d'une autre, sont trompeurs; lequel vous choisissez est une question de choisir le moins mauvais. Formellement, les deux premiers sont identiques pour le compilateur; la constante NULL
ou 0
est convertie en un pointeur nul du type de p
, et les résultats de la conversion sont comparés à p
. Peu importe la représentation d'un pointeur nul.
Le troisième est légèrement différent : p
est implicitement converti en bool
. Mais la conversion implicite est définie comme les résultats de p != 0
, donc vous finissez avec la même chose. (Ce qui signifie qu'il n'y a vraiment aucun argument valable pour utiliser le troisième style - cela obscurcit avec une conversion implicite, sans aucun bénéfice compensatoire.)
Lequel des deux premiers vous préférez est largement une question de style, peut-être partiellement dictée par votre style de programmation ailleurs : en fonction de l'idiome en question, l'un des mensonges sera plus gênant que l'autre. S'il ne s'agissait que d'une question de comparaison, je pense que la plupart des gens préféreraient NULL
, mais dans quelque chose comme f( NULL )
, le surcharge qui sera choisie est f( int )
, et non une surcharge avec un pointeur. De même, si f
est un modèle de fonction, f( NULL )
va instancier le modèle sur int
. (Bien sûr, certains compilateurs, comme g++, généreront un avertissement si NULL
est utilisé dans un contexte non-pointeur ; si vous utilisez g++, vous devriez vraiment utiliser NULL
.)
Dans C++11, bien sûr, l'idiome préféré est :
if ( p != nullptr ) ...
, ce qui évite la plupart des problèmes avec les autres solutions. (Mais cela n'est pas compatible avec C:-).)
4 votes
Ce n'est pas du c... c'est un fil c++... personnellement, je choisirais :
if(p) {...}
4 votes
Vous vous inquiétez trop - votre code est bon, même en C++. Cette discussion était entre quelques juristes du langage - c'est un peu du genre "combien d'anges peuvent danser sur la tête d'une épingle".
0 votes
@forsvarir, quand
if(p)
sera-t-il différent deif(p != NULL)
?0 votes
@cpuer: lorsque vous n'avez pas inclus un fichier d'en-tête qui définit NULL, l'un compilera, l'autre ne le fera pas...
0 votes
@forsvarir, OK, dans ce cas, c'est différent :) Mais tu n'as pas mentionné de quoi il était question dans ce fil de discussion, qui dit parfois que les pointeurs NULL peuvent avoir une valeur non nulle... Dans ce cas, à la fois
if(p)
etif(p!=NULL)
échoueront, je pense.0 votes
@cpuer Le représentant interne d'un pointeur NULL pourrait théoriquement avoir une valeur non nulle (en fait, ce n'est pas le cas), mais ce n'est pas quelque chose dont vous devez vous inquiéter.
0 votes
@Neil Butterworth, si la représentation interne du pointeur NULL n'est pas un entier non nul, les deux
if(p)
etif(p!=NULL)
échoueront, je n'ai aucune raison de ne pas m'inquiéter à ce sujet.4 votes
@cpuer Non, ils ne le feront pas car ils n'utilisent pas la représentation interne - votre code est bon! C'est ainsi que TOUS les codes C et TOUS les codes C++ sont écrits - ce fil de discussion était une discussion intellectuelle abstraite sur la rédaction de la norme C++. Vous obtenez beaucoup de cela sur les balises C++.
0 votes
@Neil Butterworth, deux fils de discussion différents sur le même sujet ont deux réponses différentes, mais je décide de rester fidèle à la mienne :)
2 votes
@cpuer: en C même
if (p != 0)
va "fonctionner" lorsque la représentation interne n'est pas entièrement constituée de bits nuls.0 votes
Ack! Je pense que le point est que même si en interne NULL n'est pas 0, un pointeur nul aura toujours la valeur de NULL. Ne définissez simplement pas
#define NULL p
, et continuez de sourire.0 votes
@pmg: et en C++ aussi. Ma tentative pour l'expliquer : dans les deux langages,
NULL
soit est un pointeur nul, soit il se convertit en pointeur nul (en C c'est dépendant de l'implémentation lequel, en C++ c'est toujours ce dernier). Et dans les deux langages, les pointeurs nuls se comparent égaux. Il est complètement indifférent que les pointeurs nuls aient tous les bits à zéro ou non,0
(ou toute autre expression constante entière avec valeur 0) etNULL
se convertissent toujours en pointeurs nuls, pas (nécessairement) en pointeurs avec tous les bits à zéro.0 votes
Ce fil de discussion discute de la possibilité de définir NULL comme ayant une valeur non nulle ou non. C est différent de C++, car en C++, NULL est 0, point final. En C, NULL est quelque chose de magique qui apparaît lorsque vous faites un transtypage de l'entier 0 en un pointeur.
1 votes
@cpuer Tant C que C++ sont (presque) identiques à cet égard. Vous ne pouvez pas comparer directement un pointeur avec un
int
. L'int
doit d'abord être converti en pointeur. Si (et seulement si) l'int
est une expression constante intégrale évaluant à 0, il y a une conversion implicite, ce qui donne un pointeur nul. (En C, il y a une autre possibilité.) Les résultats de cette conversion seront ce que l'implémentation requiert. Et si vous écrivez simplementif (p)
, le langage définit cela comme l'équivalent exact deif (p != 0)
.1 votes
@Lundin Les exigences pour la définition de
NULL
sont identiques, mot pour mot, dans les normes C et C++. Les deux exigent qu'il soit défini comme une "constante pointeur nulle". Traditionnellement,0
, mais toute "expression intégrale constante évaluée à 0" est autorisée; en C, la définition de "constante pointeur nulle" permet également de la convertir envoid*
, mais cela ne change vraiment rien. Dans les deux cas, la conversion d'une constante pointeur nulle en un pointeur nul relève de la magie du compilateur.3 votes
Pour garder les problèmes plus clairs:
NULL
est une macro, définie dans (et d'autres en-têtes).NULL
n'est pas un pointeur nul; il est requis d'être défini comme une "constante de pointeur nul" (qui en C++, ne peut pas être un pointeur, et en C, traditionnellement n'est pas un pointeur). Il y a trois concepts distincts qui doivent être traités:NULL
, un pointeur nul, et une constante de pointeur nul. Et comment un pointeur nul est physiquement représenté (son motif de bits) est complètement indépendant des deux autres.0 votes
J'ai supprimé c++ parce que en C++, la situation est complètement différente : stackoverflow.com/questions/17772103/…
0 votes
@cpuer envisageriez-vous d'accepter une réponse ? Probablement celle-ci