Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[debutant] NULL

36 réponses
Avatar
pasde.bcausse.spam
NULL n'etant pas defini en C++ ? (bizare)

dans un header Global.h j'ai

const int NULL = 0;

la ou j'utilise NULL j'ai un warning :

invalid conversion from `int' to `RXMove*' qui me parait normal

comment faire?

PS: je viens de JAVA et cela me choque :(


--
Bruno Causse
http://perso.wanadoo.fr/othello

10 réponses

1 2 3 4
Avatar
Vincent Lascaux
NULL n'etant pas defini en C++ ? (bizare)


Utilises 0.

dans un header Global.h j'ai

const int NULL = 0;


Il faudrait #define NULL 0

--
Vincent

Avatar
Anthony Fleury
NULL n'etant pas defini en C++ ? (bizare)


Le C++ définit ce qu'est un "null pointer constant", et il le définit
comme étant une valeur entière constante comparée égale à 0. Donc une
bonne définition de NULL en C++ est celle donnée en dessous. (4.10 dans
la norme)
[ En fait, d'après la norme et le paragraphe en question, on peut mettre
const int NULL = 0; ou const int NULL = 0L; si j'ai tout bien compris ].

À noter que NULL n'est qu'une macro en C aussi. C'est pas un mot clé du
C. (ce que pourrait laisser penser la phrase avec le bizarre que NULL ne
soit pas définit en C++) À noter aussi que la version C de la macro
((void*)0) est interdite du fait que la conversion de void* -> T* doit
être explicitement demandée, tout utilisateur de malloc() & co en C++
l'aura remarqué.

const int NULL = 0;
la ou j'utilise NULL j'ai un warning :
invalid conversion from `int' to `RXMove*' qui me parait normal
comment faire?


Deux choses :
- d'une part en C++ je pense qu'il est préférable de mettre 0 partout.
(c'est une question de gout, un long débat sur les groupes anglophones,
et ca fait aussi une ligne dans TC++PL)
- Cette version devrait compiler sans problème et sans warning. En
effet, la conversion est autorisée par la norme, et elle est sûre.
Quelle est la version du compilateur utilisé ? En tout cas, Comeau
Online me confirme que c'est autorisé :

const int NULL = 0;

class RxMove {
int a;
};

int main() {
RxMove* a = new RxMove;
if(NULL == a)
return -1;
else {
delete(a);
return 0;
}
}

Thank you for testing your code with Comeau C/C++!
Tell others about http://www.comeaucomputing.com/tryitout !

Your Comeau C/C++ test results are as follows:

Comeau C/C++ 4.3.0.1 (Aug 20 2002 15:39:28) for ONLINE_EVALUATION_BETA1
Copyright 1988-2002 Comeau Computing. All rights reserved.
MODE:strict errors C++


In strict mode, with -tused, Compile succeeded (but remember, the Comeau
online compiler does not link).


--
Anthony Fleury

Avatar
Jean-Marc Bourguet
(Bruno Causse) writes:

NULL n'etant pas defini en C++ ? (bizare)


C'est une macro définie par certains entêtes standards dont
cstddef.

dans un header Global.h j'ai

const int NULL = 0;


Mauvaise idée que de définir NULL soi-même. Si par hasard
tu inclus un entête qui le défini, tu vas vers des
problèmes. Mais avec la définition que tu donnes, hormis
les pb de conflis avec une définition tirée d'un entête il
ne devrait pas y avoir de problème.

la ou j'utilise NULL j'ai un warning :

invalid conversion from `int' to `RXMove*' qui me parait normal

comment faire?


En C++ c'est valide. Tu es sûr que ce n'était pas du C (où
ce devrait être une erreur; je devine: tu utilises gcc sans
-pedantic-errors?) ?

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
James Kanze
Bruno Causse wrote:
NULL n'etant pas defini en C++ ? (bizare)


NULL est très bien défini en C++, même d'une façon plus précise
qu'en C.

dans un header Global.h j'ai


const int NULL = 0;


Ce qui va donner un comportement indéfini, parce que tu n'as pas
le droit de définir NULL toi-même. (Enfin, c'est conditionné par
l'inclusion de certains en-têtes, mais dans la pratique, tu n'as
pas toujours le contrôle complet sur tout ce qui est inclu.)

la ou j'utilise NULL j'ai un warning :


invalid conversion from `int' to `RXMove*' qui me parait normal
comment faire?


#include <stddef.h>

et utiliser NULL comme d'habitude. Avec au moins un compilateur,
tu auras même des avertissements si tu essaies d'utiliser NULL
comme un entier.

Ceci dit, je ne vois pas pourquoi le compilateur émet un
avertissement. Une expression entière constate qui s'évalue à
zéro a une conversion spéciale, qui le permet de servir de
pointeur nul.

PS: je viens de JAVA et cela me choque :(


Ça choque beaucoup de gens, je crois. Mais ça fait partie de
l'héritage C.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Avatar
James Kanze
Vincent Lascaux wrote:
NULL n'etant pas defini en C++ ? (bizare)



Utilises 0.


Pourquoi ? Moi aussi, j'utilise NULL quand il s'agit d'un
pointeur.

dans un header Global.h j'ai



const int NULL = 0;



Il faudrait #define NULL 0


Comportement indéfini. Il ne faut jamais définir NULL soi-même.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


Avatar
James Kanze
Anthony Fleury wrote:

NULL n'etant pas defini en C++ ? (bizare)



Le C++ définit ce qu'est un "null pointer constant", et il le
définit comme étant une valeur entière constante comparée
égale à 0. Donc une bonne définition de NULL en C++ est celle
donnée en dessous. (4.10 dans la norme)


Sauf que l'utilisateur n'a pas le droit de le faire, dès qu'il a
inclu un parmi un certain nombre d'en-têtes.

[ En fait, d'après la norme et le paragraphe en question, on
peut mettre const int NULL = 0; ou const int NULL = 0L; si
j'ai tout bien compris ].


Selon la norme, NULL doit être 1) un macro, 2) défini dans des
en-têtes standard, et 3) évalué à une constante de pointeur nul
(qui malgré son nom, doit avoir un type entier, et non un type
pointeur).

Selon la norme, une constante de pointeur nul est n'importe
quelle expression constante de type entier dont la valeur est
zéro. Donc, 0, 0L, '', (1 - 1), ... Voir __nullptr, si le
compilateur s'arrange que __nullptr se comporte comme une
expression constante à type entier (modulo des avertissements,
dont la norme ne dit rien).

Si on utilise un compilateur qui définit NULL comme 0, ou
quelque chose de semblable, on peut discuter de la sagesse de
s'en servir. D'une part, s'en servir rend le code nettement plus
lisible, ce qui est bon en soi, mais de l'autre, il peut mener à
des surprises dans la résolution du surcharge ou dans
l'instantiation des templates.

Si on utilise un compilateur où NULL est défini comme quelque
chose comme __nullptr, et qui émet un avertissement chaque fois
qu'on essai de s'en servir comme entier, l'utilisation de NULL
n'a plus que des avantages, par rapport à 0.

À noter que NULL n'est qu'une macro en C aussi. C'est pas un
mot clé du C. (ce que pourrait laisser penser la phrase avec
le bizarre que NULL ne soit pas définit en C++) À noter aussi
que la version C de la macro ((void*)0)


C'est une des versions permises en C, mais c'est loin d'être
universelle. Dans la pratique, je crois que son utilisation se
limite aux systèmes ségmentés MS-DOS ; dans les compilateurs
dont je me suis servi sous Unix, NULL a toujours été défini
comme 0 (ou éventuellement 0L).

est interdite du fait que la conversion de void* -> T* doit
être explicitement demandée, tout utilisateur de malloc() & co
en C++ l'aura remarqué.


Je ne comprends pas trop ta phrase, ni son rapport avec NULL.
Sauf en ce qui concerne les formes permises, la définition de
NULL et des constantes de pointeur nul est identique en C et en
C++. C'est une constante « magique », avec des conversions qui
ne s'appliquent pas forcement à son type autrement.

const int NULL = 0;
la ou j'utilise NULL j'ai un warning :
invalid conversion from `int' to `RXMove*' qui me parait normal
comment faire?



Deux choses :
- d'une part en C++ je pense qu'il est préférable de mettre 0
partout. (c'est une question de gout, un long débat sur les
groupes anglophones, et ca fait aussi une ligne dans TC++PL)


Ça dépend de ton style de programmation et du compilateur dont
tu te sers. Fais-toi la règle que si le code ne se compile pas
avec g++ sans avertissements, il est incorrect, et NULL n'a que
des avantages par rapport à zéro.

- Cette version devrait compiler sans problème et sans
warning.


Ça dépend de ce qu'il a inclu avant. Si après l'expansion du
macro, le compilateur voit :

const int 0 = 0 ;

il risque de ne pas être content. Je ne crois pas que ça
explique le comportement qu'il a vu, mais il reste que sa
déclaration donne un comportement indéfini dès qu'il inclut
certains en-têtes.

En effet, la conversion est autorisée par la norme, et elle
est sûre. Quelle est la version du compilateur utilisé ? En
tout cas, Comeau Online me confirme que c'est autorisé :


const int NULL = 0;


class RxMove {
int a;
};


int main() {
RxMove* a = new RxMove;
if(NULL == a)
return -1;
else {
delete(a);
return 0;
}
}


Thank you for testing your code with Comeau C/C++!
Tell others about http://www.comeaucomputing.com/tryitout !


Your Comeau C/C++ test results are as follows:


Comeau C/C++ 4.3.0.1 (Aug 20 2002 15:39:28) for ONLINE_EVALUATION_BETA1
Copyright 1988-2002 Comeau Computing. All rights reserved.
MODE:strict errors C++


In strict mode, with -tused, Compile succeeded (but remember,
the Comeau online compiler does not link).


Sans voir le contexte complet de ton problème, c'est difficile à
dire. La solution préférée, c'est d'inclure <stddef.h> en tête,
et de se servir du NULL défini là (ou de s'en passer
complètement, et écrire 0 -- selon le compilateur, ton style de
programmation, et les conventions en vigueur où tu travailles).

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


Avatar
Fabien LE LEZ
On Sat, 07 May 2005 13:12:32 +0200, James Kanze :

Ça choque beaucoup de gens, je crois. Mais ça fait partie de
l'héritage C.


Si le mot "idiosyncrasie" n'existait pas, Bjarne l'aurait inventé ;-)

--
Le grand site de la philosophie animale : <http://perso.edulang.com/philo/>

Avatar
Anthony Fleury
Anthony Fleury wrote:
Le C++ définit ce qu'est un "null pointer constant", et il le
définit comme étant une valeur entière constante comparée
égale à 0. Donc une bonne définition de NULL en C++ est celle
donnée en dessous. (4.10 dans la norme)


Sauf que l'utilisateur n'a pas le droit de le faire, dès qu'il a
inclu un parmi un certain nombre d'en-têtes.


Ca ne me paraissait pas trivial dans la norme.
En fait, la définition apparait dans des en-tête qui sont à un moment
appelés "C++ Headers for C Library Facilities" [ les cstddef & co ]
J'ai toujours considéré ces headers comme étant fait simplement pour la
compatibilité avec le C. Mais apparement c'est bien plus. Quel est leur
statut ??

D'ailleurs, j'ai commencé le C++ en lisant TC++PL, et il y est
explicitement dit :

"En langage C, il arrivait fréquemment qu'une macro NULL soit définie
pour représenter le pointeur 0. En C++, un contrôle de type plus sérieux
rend moins problématique l'utilisation du 0 normal, plutôt que de toute
macro NULL. Le nombre de problèmes est ainsi considérablement réduit. Si
vous pensez devoir définir NULL, utilisez
const int NULL = 0;
Le qualificatif const (§5.4) évite toute redéfinition accidentelle de
NULL et permet l'utilisation dans tous les cas où une constante est
requise. "

N'est ce dont pas une grosse erreur dans TC++PL ?

[ En fait, d'après la norme et le paragraphe en question, on
peut mettre const int NULL = 0; ou const int NULL = 0L; si
j'ai tout bien compris ].


Selon la norme, NULL doit être 1) un macro, 2) défini dans des
en-têtes standard, et 3) évalué à une constante de pointeur nul
(qui malgré son nom, doit avoir un type entier, et non un type
pointeur).


Comme dit plus haut, comme cette définition n'apparaissait que dans les
en-tête <cX> avec X un nom d'en-tête C, je pensais pas que le fait que
ce soit une macro était obligatoire en C++. Pour moi la norme du C++ ne
définissait pas NULL.

est interdite du fait que la conversion de void* -> T* doit
être explicitement demandée, tout utilisateur de malloc() & co
en C++ l'aura remarqué.


Je ne comprends pas trop ta phrase, ni son rapport avec NULL.
Sauf en ce qui concerne les formes permises, la définition de
NULL et des constantes de pointeur nul est identique en C et en
C++.


Ce que je voulais dire, c'est que certains compilateurs C définissent
NULL comme (void*)0. (ca fait même l'objet d'une note dans la norme
C++). Et cette forme est interdite en C++, qui a des règles de
conversions plus fortes sur ce point que le C. En effet, le code :

#include <stdlib.h>

int main(void) {
int *a = malloc(sizeof *a);
free(a);
return 0;
}

est valable en C mais pas en C++. Le C++ requiert un cast explicite pour
caster void* -> T* que ne requiert pas le C.

Deux choses :
- d'une part en C++ je pense qu'il est préférable de mettre 0
partout. (c'est une question de gout, un long débat sur les
groupes anglophones, et ca fait aussi une ligne dans TC++PL)


Ça dépend de ton style de programmation et du compilateur dont
tu te sers. Fais-toi la règle que si le code ne se compile pas
avec g++ sans avertissements, il est incorrect, et NULL n'a que
des avantages par rapport à zéro.


Pour ma part j'ai pris l'habitude en C++ d'utiliser 0, mais c'est vrai
que NULL peut être plus lisible. Ca dépend en effet du style de
programmation. [ pour ma part comme dit plus haut ca a surtout été
conditionné par la lecture de TC++PL, et ca fait une différence par
rapport au C où j'utilise tout le temps NULL. ]

- Cette version devrait compiler sans problème et sans
warning.


Ça dépend de ce qu'il a inclu avant. Si après l'expansion du
macro, le compilateur voit :

const int 0 = 0 ;

il risque de ne pas être content. Je ne crois pas que ça
explique le comportement qu'il a vu, mais il reste que sa
déclaration donne un comportement indéfini dès qu'il inclut
certains en-têtes.


En effet ca n'explique pas son problème car cette ligne provoquerait une
erreur de syntaxe, car en gros il trouve un entier là où un identifiant
est attendu. C'est donc incorrecte. Mais en effet après inclusion de
certains en-tête, cette définition de NULL poserait des problèmes. Je ne
savais par contre pas que ca provoquait un comportement indéfinit de
redéfinir NULL.

Sans voir le contexte complet de ton problème, c'est difficile à
dire. La solution préférée, c'est d'inclure <stddef.h> en tête,
et de se servir du NULL défini là (ou de s'en passer
complètement, et écrire 0 -- selon le compilateur, ton style de
programmation, et les conventions en vigueur où tu travailles).


Et en entreprise ca doit aussi dépendre du style de la boîte non ? dans
la coordination d'un projet ca doit faire partie des styles de
programmation qui sont définis je suppose ?

--
Anthony Fleury


Avatar
Hamiral
PS: je viens de JAVA et cela me choque :(


Sauf qu'en Java, le mot-clé null n'a rien à voir avec les pointeurs, et
pour cause : il n'y a pas de pointeur en Java, mais des /références/ sur
des objets. Et le mot-clé null sert en Java à dire qu'une variable ne
fait référence à aucun objet.

Bon, Ok, je pinaille, mais c'est ma spécialité (le pinaillage) :)

Avatar
Richard Delorme

"En langage C, il arrivait fréquemment qu'une macro NULL soit définie
pour représenter le pointeur 0. En C++, un contrôle de type plus sérieux
rend moins problématique l'utilisation du 0 normal, plutôt que de toute
macro NULL. Le nombre de problèmes est ainsi considérablement réduit. Si
vous pensez devoir définir NULL, utilisez
const int NULL = 0;
Le qualificatif const (§5.4) évite toute redéfinition accidentelle de
NULL et permet l'utilisation dans tous les cas où une constante est
requise. "

N'est ce dont pas une grosse erreur dans TC++PL ?


Non, tout est dans le "Si vous pensez devoir définir", qui suppose que
l'on veut se passer des entêtes et définir NULL soi-même.

--
Richard

1 2 3 4