OVH Cloud OVH Cloud

[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
Pierre THIERRY
Le Sun, 08 May 2005 17:50:25 +0200, James Kanze a écrit :
Pas vraiment. Dans la mésure qu'une telle définition est interdite, il
faut le dire. C'est un peu comme si on disait : « Si vous pensez
devoir modifier la même variable deux fois dans la même expression...
».


i = ++i + i++;

Ça compile parfaitement, c'est légal.

Brièvement,
Nowhere man
--

OpenPGP 0xD9D50D8A

Avatar
kanze
Pierre THIERRY wrote:
Pas vraiment. Dans la mésure qu'une telle définition est
interdite, il faut le dire. C'est un peu comme si on disait
: « Si vous pensez devoir modifier la même variable deux
fois dans la même expression... ».


i = ++i + i++;

Ça compile parfaitement, c'est légal.


Tu as oublié l'émoticon -- quelqu'un risque de te prendre au
sérieux.

Juste au cas où : ce n'est pas légal, c'est un comportement
indéfini. C-à-d que le compilateur n'est pas obligé à émettre un
avertissement, et que le langage ne donne aucune signification à
l'expression -- quoiqu'il arrive (y compris le formattage du
disque dur), le compilateur a raison.

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


Avatar
kanze
Anthony Fleury wrote:
Anthony Fleury wrote:



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


Il y a deux partie de l'énoncé. Le conseil de définir
soi-même NULL est une grosse erreur, certainement. Le
conseil de préférer 0, en revanche, relève de l'opinion
personnelle ; on peut regretter que Stroustrup n'a pas
présenté d'autres avis aussi, mais on ne peut pas lui nier
le droit à son opinion.


N'empêche que ce passage est très peu clair pour quelqu'un qui
apprend le C++ avec ce livre, et en tant que premier lien avec
le langage, ca laisse des traces !


Je le trouve un peu regrettable aussi.

De l'autre côté, c'est bien rare, des livres où on est 100%
d'accord avec l'auteur. Dans l'ensemble, TC++PL fait bien mieux
que la plupart.

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.


Et qu'en fais-tu de §18.1 ?


§18.1 parle de NULL définie dans <cstddef>, donc tout découle
de la même erreur qu'au dessus. Le point 4 nous dit que NULL
est une macro dont la définition respecte le §4.10, qui dit ce
que j'ai énoncé plus haut. Pour moi (et toujours dans la même
idée), cette macro était définie comme ca pour que l'inclusion
de <cstddef> soit possible en C++, donc avec une macro NULL
compatible.


C'est certain que la compatabilité C a joué un rôle non
negligeable ici. Mais il reste que même dans <cstddef>, quelque
chose comme ptrdiff_t sert aussi en C++.

[...]
Je crois qu'il y a un consensus pour dire que cette
situation est lamentable, ou au moins, moins d'idéale. Pas,
en revanche, sur ce qu'il faut faire en consequence. (Je
crois qu'il y a une proposition devant le gremium C++ pour
une véritable solution -- Gaby pourrait peut-être en donner
plus de détails. Je serais pour, ne serait-ce que pour
arrêter toutes ces discussions interminables:-).)


http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1601.pdf
Celle ci ?


Tout à fait.

J'avais lu aussi suite à un lien donné par Gabriel Dos Reis
ici même. Ca a l'air interessant en effet. Pour ma part je ne
vois pas toute l'implication de la proposition, vu qu'hormis
dans cette discussion, je n'ai jamais eu de problème avec un
pointeur null en C++.


Moi non plus, en C++, sur des machines modernes. Une ou deux
fois quand j'ai commencé le C, en revanche. En suivant
exactement ce qui était écrit dans les pages de man -- dans les
pages de man de Unix V7, l'exemple de execl était :

int execl( path, arg0, ..., 0 ) ;

Ce qui ne marche pas sur une machine où sizeof( int )
!= sizeof( char* ).

Formellement, la seule solution légale, c'est de bien caster le
0 final (y compris si c'est écrit NULL). Dans la pratique, tous
les compilateurs que je connais s'arranger pour que sizeof( NULL )
== sizeof( char* ), et donc, que le code marchait, comportement
indéfini ou non. (La solution "standard" sur des machines Unix
était d'utiliser 0L, s'il fallait. Sous Windows, on a "inventé"
la solution ((void*)0). Mais note que dans les deux cas, il
s'agit de faire marcher du code qui est formalement incorrect.)

Personnellement, et ça n'engage que moi, je trouve qu'on
pourrait bien introduire une catégorie supplémentaire des
erreurs, entre un comportement indéfini et un diagnostique
obligatoire, qui délimite les dégats possibles à la phase de
compilation -- si le compilateur ne râle pas, ça doit
marcher. Parce que ce genre de cas n'est pas rare dans la
norme. (Mais ce n'est pas si évident que ça -- si ensuite
d'une inclusion « cachée » d'un en-tête, tu vois plus ou
moins d'un ensemble de fonctions surchargées, la résolution
du surcharge peut bien être différente, sans pour autant
provoquer une erreur de compilation.)


Et dans ce cas, bonjour l'amusement pour debugger aussi...
Surtout quand c'est la première fois qu'on tombe sur le
problème.


Tout à fait. C'est l'argument contre NULL, et même si je ne suis
pas convaincu, je reconnais qu'il a un certain poids.

Tout à fait. Encore que je dois dire que chaque fois que
j'ai vu oùla question s'est posée, la décision s'est faite
pour NULL, plutôt que 0.


C'est une sorte de "mot clé" notamment pour tout ceux qui ont
fait du C. (pas taper sur l'expression "mot clé", mais j'ai
pas trouvé mieux) C'est donc en effet plus clair pour tout le
monde, et tous les relecteurs du code.


Je crois que « mot clé », c'est bien l'expression qui convient.
Peut-être pas dans le sens de la norme:-), mais c'est
effectivement comme ça que je le vis aussi.

Mais je crois aussi que ceux qui préfère 0 vivent 0 comme un
espèce de mot clé.

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



Avatar
kanze
Fabien LE LEZ wrote:
On Sun, 08 May 2005 17:53:59 +0200, James Kanze :

-- Les pointeurs de Java ne sont pas des objets en soi -- en ne
peut pas en prendre l'adresse, par exemple.

-- Le Java ne supporte pas l'arithmétique sur des pointeurs.


C'est ce qu'on appelle "référence" en C++, non ?


Pas vraiment. Une référence en C++ est un alias pour un objet.
Un autre nom. L'objet en est fixé une fois pour tout, lors de
l'initialisation, et il y a bien un objet. En Java, une
référence se comporte plutôt comme un pointeur en C++, en dehors
de l'absense de l'arithmétique -- c'est vrai qu'on ne peut pas
en prendre l'adresse, non plus, mais ça, c'est aussi vrai pour
double ou pour int.

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


Avatar
kanze
Matthieu Moy wrote:
Fabien LE LEZ writes:

Bon, on va dire que la notion de pointeur en Java est à
mi-chemin entre les pointeurs et les références en C++ ;-)


Y'a des grands débats pour savoir si il y a des « pointeurs »
en Java. Vu qu'il y a un java.lang.NullPointerException, on
serait tenté de dire oui, mais on dit aussi qu'on ne manipule
que des références.

Si j'ai bien compris, la version officielle est que la
variable est une référence, et sa valeur est un pointeur.


Et ici, de noter qu'il ne correspond ni aux pointeurs, ni aux
références en C++. C'est encore une autre bête -- plus proche
d'un pointeur que d'une référence C++, mais différente, quand
même.

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


Avatar
kanze
Lambda wrote:
est-ce qu'on pourrait écrire un glaneur de cellules en Java ?


Allez, une petite réponse passe-partout pour le plaisir...

"Java est Turing-complete"


Quel rapport ? Il ne s'agit pas ici de la possibilité
d'implémenter un algorithme quelconque, mais de la possibilité
d'accéder aux niveaux assez bas de la machine.

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


Avatar
Vincent Lascaux
Je rajoute i=0 pour la suite

i = ++i + i++;


Juste au cas où : ce n'est pas légal, c'est un comportement
indéfini. C-à-d que le compilateur n'est pas obligé à émettre un
avertissement, et que le langage ne donne aucune signification à
l'expression -- quoiqu'il arrive (y compris le formattage du
disque dur), le compilateur a raison.


Tu es sur ? J'aurais effectivement dit que c'était un comportement
"indéfini" dans la mesure où le compilo a le droit d'évaluer ++i ou i++ dans
l'ordre qu'il veut.
S'il évalue en premier ++i, ca fait i = 1 + 1, sinon, ca fait i = 2 + 0 (ce
qui fait la même chose, ce qui n'aurait pas été le cas avec i = ++i + i--
(i=1+1 ou i=0+0)).
J'aurais dit qu'il y avait comportement indéfini parmis un ensemble (fini)
de comportements défini (évaluer l'expression de gauche ou celle de droite
en premier).

--
Vincent


Avatar
Fabien LE LEZ
On Mon, 9 May 2005 13:16:27 +0200, "Vincent Lascaux"
:

S'il évalue en premier ++i, ca fait i = 1 + 1, sinon, ca fait i = 2 + 0 (ce
qui fait la même chose, ce qui n'aurait pas été le cas avec i = ++i + i--
(i=1+1 ou i=0+0)).


La norme n'impose rien, donc un compilateur qui renverrait autre chose
que 2 serait parfaitement en accord avec la norme (d'après ce que j'ai
compris du message de James). Par contre, on pourrait de poser des
questions sur la qualité du compilateur, et avoir une légère tendance
à en essayer un autre à la place...

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

Avatar
Jean-Marc Bourguet
"Vincent Lascaux" writes:

Je rajoute i=0 pour la suite

i = ++i + i++;


Juste au cas où : ce n'est pas légal, c'est un comportement
indéfini. C-à-d que le compilateur n'est pas obligé à émettre un
avertissement, et que le langage ne donne aucune signification à
l'expression -- quoiqu'il arrive (y compris le formattage du
disque dur), le compilateur a raison.


Tu es sur ? J'aurais effectivement dit que c'était un comportement
"indéfini" dans la mesure où le compilo a le droit d'évaluer ++i ou
i++ dans l'ordre qu'il veut.


C'est un comportement indéfini et le compilateur peut faire tout ce
qu'il veut. Même des choses pas raisonnables. Il n'y a pas en C++ de
notion équivalente aux "bounded errors" d'Ada qui limitent ce qui est
possible.

S'il évalue en premier ++i, ca fait i = 1 + 1, sinon, ca fait i = 2
+ 0 (ce qui fait la même chose, ce qui n'aurait pas été le cas avec
i = ++i + i-- (i=1+1 ou i=0+0)).


Dans les comportements "raisonnables" pour évaluer i = ++i + i++, il y
a au moins 1 et 2; mais rien ne garanti un comportement raisonnable.
Ici, j'ai valeur 3 et en regardant l'assembleur je n'ai aucune
indication du pourquoi: l'optimiseur a fait son travail et remplacé le
code par i=3; quand on ne respecte pas les hypothèses d'un optimiseur,
ce n'est pas étonnant d'avoir des choses de ce genre. Une possibilité
d'interprétation du résultat. i = ++i + i++;

Je commence par faire ++i, le résultat est stocké dans i (puisque
c'est un registre). Donc, i vaut 1 et ++i vaut i.

Je fais i++, valeur c'est 1, je modifie i qui vaut maintenant 2.

Je dois faire la somme de ++i (ça se trouve dans i) et de i++ (c'est
2). Ok j'ai 2 + 1 ce qui fait 3.

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
Jean-Marc Bourguet
Fabien LE LEZ writes:

On Mon, 9 May 2005 13:16:27 +0200, "Vincent Lascaux"
:

S'il évalue en premier ++i, ca fait i = 1 + 1, sinon, ca fait i = 2 + 0 (ce
qui fait la même chose, ce qui n'aurait pas été le cas avec i = ++i + i--
(i=1+1 ou i=0+0)).


La norme n'impose rien, donc un compilateur qui renverrait autre chose
que 2 serait parfaitement en accord avec la norme (d'après ce que j'ai
compris du message de James). Par contre, on pourrait de poser des
questions sur la qualité du compilateur, et avoir une légère tendance
à en essayer un autre à la place...


Je ne me pose pas de questions sur l'optimiseur du compilateur que
j'ai utilisé. De même que je comprendrais très bien une valeur de 1.

Je commence par évaluer i++, résultat 0, j'ai à faire dans le futur i=1.
J'évalue ++i, i vaut 0 pour le moment, résultat 1, j'ai à faire i = 1.
0+1 ça fait 1 chez moi, je le stocke dans i 3 fois de suite.

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


1 2 3 4