J'aimerais savoir comment tester si un pointeur sur un objet a bien été initialisé ?
MaClasse *obj;
if(obj != NULL) // c'est toujours vrai apparement
Version imprimable
J'aimerais savoir comment tester si un pointeur sur un objet a bien été initialisé ?
MaClasse *obj;
if(obj != NULL) // c'est toujours vrai apparement
Dans le doute, pars du posulat que tu ne peux pas prévoir ce qui se trouve dans la zone mémoire que tu viens d'allouer. Il est donc vivement conseillé d'assigner la valeur 0 à ton pointeur lors de sa déclaration, et juste après sa desallocation.
Code:
1
2
3
4
5
6 Object* obj = 0; obj = truc; delete obj; obj = 0;
Ton 'if' est toujours vrai car lorsque tu fais seulement:
Tu n'as pas allouer de mémoire pour ton pointeur (donc il ne pointe nul part). Il est donc égal à NULL.Code:Object *obj;
Si tu fais:
Tu alloues dynamiquement de la mémoire pour ton pointeur et donc s'il n'y a pas eu un manque de mémoire (ou autre problème d'allocation de mémoire), ton pointeur ne sera plus égal à NULL.Citation:
Object *obj = new Object;
Bonne continuation.
Une variable d'un type primitif non initialisée reste non initialisée, sauf options du compilo paticulières ; elle contient donc n'importe quoi.Citation:
Envoyé par vdumont
Donc dire qu'ici le pointeur est égal à NULL est une grosse erreur, qui se payera au mieux immédiatement, au pire lorsque tu livreras ton appli au client ;)
C'est le genre de trucs que tu t'en rends jamais compte avant d'avoir livré, parce qu'en debug ca passe alors qu'en release ca explose :mrgreen:Citation:
Envoyé par Laurent Gomila
Donc le mieux c'est toujours intialiser les variables, en l'occurence faire MaClasse *obj = NULL;
Et avec un bon réglage du compilateur, ce genre d'erreur ne sera pas permise.
Le problème de savoir si une variable est initialisée ou non est indécidable dans sa generalite. Le compilateur peut avertir sur des cas particuliers (ou accepter d'avertir de donner des faux positifs).Citation:
Envoyé par Ulmo
> thx, je vais compléter mes constructeurs.Citation:
Envoyé par Neo41
> J'achete!Citation:
Envoyé par NewbiZ
vdumont, si mon test est vrai c bien que le pointeur n'est pas NULL!
> Option du compilo! Hey ça m'interesse. Est ce qu'on peut forcer le compilo à donner la valeur NULL a 1 objet non initialisé ?Citation:
Envoyé par Laurent Gomila
> Dis m'en plus stp.Citation:
Envoyé par Ulmo
Jean-Marc.Bourguet tu peux reformuler stp, jai pas bien saisi!
Salut,
Ce que jean marc voulait dire, c'est que si tu choisi les bonnes options de compilation (que tu le regle en mode "paranoïaque", par exemple), ton compilateur criera au scandale chaque fois que tu feras l'erreur...
S'il accepte de continuer la compilation, tu auras au moins un avertissement, dont il t'appartiendra de le prendre en compte.
> tu parles de -Wall -ansi ?Citation:
Envoyé par koala01
Tu connais la différence entre NULL et 0 ?Citation:
Envoyé par NewbiZ
L'un a une valeur documentaire qui dit "en théorie, on m'emploie sur des pointeurs, et m'affecter à un entier relève de la volonté de nuire". Généralement, sur les pointeurs, c'est celui-là qu'on emploie...
Personnellement, ça ne me choque pas de voir un 0 au lieu d'un NULL (je fais pareil). Juste un petit quote à ce sujet :Citation:
Tu connais la différence entre NULL et 0 ?
L'un a une valeur documentaire qui dit "en théorie, on m'emploie sur des pointeurs, et m'affecter à un entier relève de la volonté de nuire". Généralement, sur les pointeurs, c'est celui-là qu'on emploie...
Citation:
If you have to name the null pointer, call it nullptr; that's what it's going to be called in C++0x. Then, "nullptr" will be a keyword.
Les opinions sont assez divergentes sur le sujet. De bons auteurs (Stroustrup en tete si j'ai bonne memoire) preconisent l'utilisation de 0.Citation:
Envoyé par Médinoc
Personnellement, j'utilise NULL.
Là, je suis sur le cul.Citation:
Envoyé par Jean-Marc.Bourguet
Pour moi, c'est mélanger les torchons et les serviettes, ce qu'un langage fortement typé est justement censé aider à éviter... 8O
Le probleme c'est que NULL n'est en rien different de 0 (en C++, en C c'est pire, ce peut etre mais pas obligatoirement (void*)0). Donc l'utilisation de NULL n'a qu'une valeur de commentaire et a un comportement bizarre en cas de surcharge et de resolution de template si on pense a lui comme un pointeur. Ils le trouvent donc dangereux. (Et certains ont ete brules dans le passe avec le partage d'entete avec C faisant que NULL etait defini comme (void*)0, ce qui ne doit plus arriver depuis un quinzaine d'annees).Citation:
Envoyé par Médinoc
Je sais que par défaut, le mode Debug de VS le fait alors que le mode release ne le fait pas (d'où certain bug qui n'apparaissent qu'en release) (source). C'est lié au optimisations. Il reste que compter sur le compilateur n'est pas la bonne solution.Citation:
Envoyé par hogan
Pour GCC je ne sais pas commen ça se passe. Donc pareil, il ne faut pas compter dessus.
Pour VS : Project/Properties/C++/General/Warning Level à mettre au niveau 4Citation:
> Dis m'en plus stp.
Pour gcc : -Wall -W
Il me semble que le debugger de VS initialise au contraire les variables à une valeur forcément invalide (0xCCCCCCCC pour les variables sur la pile) histoire d'aider au débogage...
Tu as raison, ma source parlait plutôt des variables entières.
> pas mal! Mais mieux vaut s'en passer si on veut pouvoir porter son code. Puis en initialisant les variables avec 1 valeur par défaut on gagne en lisibilité n'est ce pas!Citation:
Envoyé par Médinoc
> effectivement on retrouve bien 0 comme valeur par défaut dans beaucoup de source du c++ mais le NULL y est tt aussi répendu. A mon sens c'est plus un pb de conformité par rapport à l'écriture adoptée...il vaut mieux utiliser 1 seul représentation pour rester cohérent. L'idéal serait peut être de faire un typedef de façon à pouvoir switcher facilement de l'un vers l'autre.Citation:
Envoyé par Jean-Marc.Bourguet
De vieux restes de C surement :mrgreen:Citation:
> effectivement on retrouve bien 0 comme valeur par défaut dans beaucoup de source du c++ mais le NULL y est tt aussi répendu. A mon sens c'est plus un pb de conformité par rapport à l'écriture adoptée...il vaut mieux utiliser 1 seul représentation pour rester cohérent. L'idéal serait peut être de faire un typedef de façon à pouvoir switcher facilement de l'un vers l'autre.
En vérité tu trouvera typiquement dans tes fichiers include un
pour les compilateurs C++, et unCode:#define NULL 0
pour les compilateurs C.Code:#define NULL ((void*)0)
Il y a donc stricte équivalence entre les 2 du point de vue technique. Pour ce qui est de la théorie, Jean-Marc.Bourguet a très bien résumé la situation ^^
> hum je sui pas plus famillié au C je compren pa prkoi tu a fait la remark lol.Citation:
Envoyé par NewbiZ
En tout cas c bien dommag, jaurai bien aimé garder la mm écriture entre le C# et le C++. Pour info en C# on utilise null ds le but d'initialiser les références.
Et en C++/CLI, on utilise nullptr. :)
NULL apartient à C... même en C++ NULL est du domaine C puisqu'il est déclarer dans le préprocesseur
C'est pourquoi plusieurs utilisent 0, c'est autant auto-documenté que NULL.Code:#define NULL 0
est autant, sinon plus, lisible queCode:Truc *machin = 0;
ainsi que plusieurs utilisentCode:Truc *machin = NULL;
pour valider que le pointeur est initialiséCode:if( !machin )
sachant que 0 en C++ vaut false et toutes les autres valeurs valent true.
NULL n'est donc plus viable en C++, c'est du C
0 n'est pas "autant auto-documenté" que NULL, car quand on voit 0, on pense "entier".
Quand on voit NULL, on pense "pointeur". Et ce, qu'on vienne de C, C#, ou même Java.
On ne nie absolument pas que NULL soit un héritage du C...
D'ailleurs, quand tu y regarde d'un peu plus pres, il y a de nombreuses choses dans l'espace de nommage std qui ne sont que des héritages du C... (bien souvent, au mieux, avec un #undef hors de l'espace de nommage, et un #define exactement identique celui du C à l'intérieur :P)
Et pour cause: le C++ revendique de descendre du C... tout en revendiquant une différence par rapport à lui ;)
Cependant, je rejoint fortement l'avis (une fois n'est pas coutume) de médinoc: NULL est à mon sens bien plus autocommenté que 0...
N'oublions jamais que l'on peut décider de remettre un pointeur à 0/NULL à n'importe quel moment (idéalement, apres avoir quand meme pensé à libérer la mémoire vers laquelle il pointait :P) et que, en dehors de tout autre système auto-commenté (tous les noms variables "pointeurs" ne commencent pas forcément par un ptr_ ni meme par un p*), il devient rapidement difficile, parmis, parfois, plusieurs centaines de lignes de code, de se rappeler que telle ou telle variables est un pointeur et non un entier en voyant simplement
...Ce qui pourrait très bien arriver si la libération de la mémoire est déléguée à une fonction qui aurait été appelée quelques lignes plus tot...Code:variable=0;
C'est la raison pour laquelle, je préférerai toujours également tester un pointeur sous la forme de
plustot que sous celle deCode:if(variable !=NULL)
bien qu'en définitive, les deux formes soient effectivement équivalentes...Code:if(!variable)
Je sais que le C et le C++ fournissent énormément de "raccourcis" qui peuvent sembler très intéressant à première vue...
Mais il ne faut jamais oublier que ces raccourcis ont pour la plupart l'énorme inconvéniant de forcer à une réfléxion plus importante lorsque l'on (re)découvre un code inconnu/oublié...
Ces raccourcis datent, pour la plupart (tous serait d'ailleurs plus juste), d'un temps où tout était à faire, y compris dans le domaine des éditeurs de texte...
Ils permettaient de gagner quelques (dizièmes) de seconde à chaque fois qu'ils étaient utilisés, et faisaient, au final, gagner un temps non négligeable sur plusieurs centaines de lignes/instructions...ou sur l'ensemble d'un projet...
L'inconvéniant était que le code fourni perdait en compréhensibilité aux yeux d'une personne qui n'aurait pas participé directement au codage meme ou qui l'aurait laissé de coté pendant un temps plus ou moins long...
Mais, maintenant, avec l'évolution de tous les éditeurs de texte (y compris vim et emacs), et, principalement celles qui ont trait à l'auto-complétion et au copier/coller, on ne perd absolument pas de temps à laisser les raccourcis de coté, mais, par contre, qu'est-ce qu'on gagne, en le faisant, au niveau de la compréhension du code :P...
[EDIT]maintenant, je n'ai fait qu'émettre mon avis strictement personnel... mais je le partage :D
Je suis 100% d'accord avec toi sur le fond (d'ailleurs, j'ai tendance à corriger quand je tombe sur un de mes anciens programmes), mais sur la forme, les deux formules ici décrites ne sont PAS équivalentes, mais opposées :pCitation:
Envoyé par koala01
---> Le premier test est vrai si le pointeur n'est pas null, le second test est vrai s'il l'est...
Enfin, sans doute une faute d'inattention, qui ne change rien à l'argument.
Argument auquel je réponds un gros:
+1
Et +1 aussi pour la suite du post.
Il ne faut pas exagere: les namespace n'ont aucun rapport sur la portee et la visibilite des macros.Citation:
Envoyé par koala01
Sur le fond je suis d'accord, mais il faut savoir que l'utilisation de 0 plutot que de NULL, l'elision de la comparaison a 0 de pointeurs ou d'entier est suffisemment repandue pour qu'on doive considere les deux comme idiomatiques.