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 ?
§5/4 (deuxième phrase) : Between the previous and the next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.
Dans l'expression ci-dessus, le seul point de séquencement, c'est la fin de l'expression complète. (Certains opérateurs, comme le &&, le || et le ?, introduisent aussi des points de séquencements.)
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.
§1.3.12 :
undefined behavior
behavior, such as might arise upon use of an erroneaous program construct or erroneaous data, for which this International Standard imposes no requirements.
Ensuite, il y a une note avec des exemples (non-exhaustifs) des comportements possibles.
Tu peux considérer la norme comme un espèce de contrat entre toi et le compilateur. Tu as violé les termes du contrat. Le compilateur n'y est plus tenu.
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 la pratique, un bon compilateur ne va pas faire exprès pour rendre les résultats désagréables. Dans ce cas-ci, donc, sans optimisation, je m'attendrais bien à un résultat entre 0 et 2. (Avec optimisation, c'est moins clair, mais c'est probable aussi que le résultat se trouve entre ces bornes). Et un réformattage du disque dur m'étonnerait beaucoup. (Mais j'ai déjà vu le contenu d'une diskette detruite au point qu'on ne pouvait plus rien lire suite à un comportement indéfini.)
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).
Ça s'appelle un comportement non-spécifié (unspecified behavior) dans la norme. C'est autre chose. Donc, par exemple, dans f(g(),h()), l'ordre de l'appel de g() et de h() n'est pas spécifié, mais il faut bien que le compilateur en appelle une, puis l'autre.
La norme dit explicitement que dans le cas en question, le comportement n'est pas défini.
-- 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
Vincent Lascaux wrote:
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 ?
§5/4 (deuxième phrase) :
Between the previous and the next sequence point a scalar
object shall have its stored value modified at most once by
the evaluation of an expression.
Dans l'expression ci-dessus, le seul point de séquencement,
c'est la fin de l'expression complète. (Certains opérateurs,
comme le &&, le || et le ?, introduisent aussi des points de
séquencements.)
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.
§1.3.12 :
undefined behavior
behavior, such as might arise upon use of an erroneaous
program construct or erroneaous data, for which this
International Standard imposes no requirements.
Ensuite, il y a une note avec des exemples (non-exhaustifs) des
comportements possibles.
Tu peux considérer la norme comme un espèce de contrat entre toi
et le compilateur. Tu as violé les termes du contrat. Le
compilateur n'y est plus tenu.
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 la pratique, un bon compilateur ne va pas faire exprès pour
rendre les résultats désagréables. Dans ce cas-ci, donc, sans
optimisation, je m'attendrais bien à un résultat entre 0 et 2.
(Avec optimisation, c'est moins clair, mais c'est probable aussi
que le résultat se trouve entre ces bornes). Et un réformattage
du disque dur m'étonnerait beaucoup. (Mais j'ai déjà vu le
contenu d'une diskette detruite au point qu'on ne pouvait plus
rien lire suite à un comportement indéfini.)
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).
Ça s'appelle un comportement non-spécifié (unspecified behavior)
dans la norme. C'est autre chose. Donc, par exemple, dans
f(g(),h()), l'ordre de l'appel de g() et de h() n'est pas
spécifié, mais il faut bien que le compilateur en appelle une,
puis l'autre.
La norme dit explicitement que dans le cas en question, le
comportement n'est pas défini.
--
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
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 ?
§5/4 (deuxième phrase) : Between the previous and the next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.
Dans l'expression ci-dessus, le seul point de séquencement, c'est la fin de l'expression complète. (Certains opérateurs, comme le &&, le || et le ?, introduisent aussi des points de séquencements.)
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.
§1.3.12 :
undefined behavior
behavior, such as might arise upon use of an erroneaous program construct or erroneaous data, for which this International Standard imposes no requirements.
Ensuite, il y a une note avec des exemples (non-exhaustifs) des comportements possibles.
Tu peux considérer la norme comme un espèce de contrat entre toi et le compilateur. Tu as violé les termes du contrat. Le compilateur n'y est plus tenu.
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 la pratique, un bon compilateur ne va pas faire exprès pour rendre les résultats désagréables. Dans ce cas-ci, donc, sans optimisation, je m'attendrais bien à un résultat entre 0 et 2. (Avec optimisation, c'est moins clair, mais c'est probable aussi que le résultat se trouve entre ces bornes). Et un réformattage du disque dur m'étonnerait beaucoup. (Mais j'ai déjà vu le contenu d'une diskette detruite au point qu'on ne pouvait plus rien lire suite à un comportement indéfini.)
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).
Ça s'appelle un comportement non-spécifié (unspecified behavior) dans la norme. C'est autre chose. Donc, par exemple, dans f(g(),h()), l'ordre de l'appel de g() et de h() n'est pas spécifié, mais il faut bien que le compilateur en appelle une, puis l'autre.
La norme dit explicitement que dans le cas en question, le comportement n'est pas défini.
-- 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
kanze
Fabien LE LEZ wrote:
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 veux bien qu'il ne réformatte pas le disque dur, mais je ne vois pas pourquoi il renverrait forcément 2. Sans parler de la valeur finale d'« i » (qui pourrait bien être différent de ce que l'expression renvoie). C'est assez courant, je crois, de différer les effets de bord -- ++i peut bien décider que le résultat est 1, mais ne le réécrire dans la mémoire qu'à la fin de l'expression, après l'écriture due à l'affectation. (Chez moi, Sun CC renvoie 3, tandis que g++ renvoie 2. D'autres valeurs sont possibles.)
-- 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
Fabien LE LEZ wrote:
On Mon, 9 May 2005 13:16:27 +0200, "Vincent Lascaux"
<nospam@nospam.org>:
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 veux bien qu'il ne réformatte pas le disque dur, mais je ne
vois pas pourquoi il renverrait forcément 2. Sans parler de la
valeur finale d'« i » (qui pourrait bien être différent de ce
que l'expression renvoie). C'est assez courant, je crois, de
différer les effets de bord -- ++i peut bien décider que le
résultat est 1, mais ne le réécrire dans la mémoire qu'à la fin
de l'expression, après l'écriture due à l'affectation. (Chez
moi, Sun CC renvoie 3, tandis que g++ renvoie 2. D'autres
valeurs sont possibles.)
--
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
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 veux bien qu'il ne réformatte pas le disque dur, mais je ne vois pas pourquoi il renverrait forcément 2. Sans parler de la valeur finale d'« i » (qui pourrait bien être différent de ce que l'expression renvoie). C'est assez courant, je crois, de différer les effets de bord -- ++i peut bien décider que le résultat est 1, mais ne le réécrire dans la mémoire qu'à la fin de l'expression, après l'écriture due à l'affectation. (Chez moi, Sun CC renvoie 3, tandis que g++ renvoie 2. D'autres valeurs sont possibles.)
-- 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
Pierre THIERRY
Le Mon, 09 May 2005 02:59:17 -0700, kanze a écrit :
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.
int i = 1; int* adr_i = &i;
On peut prendre l'adresse de n'importe quelle variable...
Dubitativement, Nowhere man --
OpenPGP 0xD9D50D8A
Le Mon, 09 May 2005 02:59:17 -0700, kanze a écrit :
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.
int i = 1;
int* adr_i = &i;
On peut prendre l'adresse de n'importe quelle variable...
Dubitativement,
Nowhere man
--
nowhere.man@levallois.eu.org
OpenPGP 0xD9D50D8A
Le Mon, 09 May 2005 02:27:51 -0700, kanze a écrit :
Tu as oublié l'émoticon -- quelqu'un risque de te prendre au sérieux.
Au temps pour moi. J'ai encore tendance à faire l'amalgame entre « ça compile et ça s'exécute » et « le code est conforme à la norme ».
Je ferai plus, c'est promis.
Honteusement, Nowhere man --
OpenPGP 0xD9D50D8A
kanze
Pierre THIERRY wrote:
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.
int i = 1; int* adr_i = &i;
On peut prendre l'adresse de n'importe quelle variable...
On discutait les différences entre les pointeurs de C++ et les références de Java. On ne peut pas prendre l'adresse d'un pointeur en Java (à l'encontre de C++), mais ce n'est pas vraiment une différence entre les références de Java et des pointeurs de C++, parce que la même chose vaut pour les autres types de base. En Java, les objets ont une adresse, mais non les variables (ni les éléments d'un objet).
-- 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
Pierre THIERRY wrote:
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.
int i = 1;
int* adr_i = &i;
On peut prendre l'adresse de n'importe quelle variable...
On discutait les différences entre les pointeurs de C++ et les
références de Java. On ne peut pas prendre l'adresse d'un
pointeur en Java (à l'encontre de C++), mais ce n'est pas
vraiment une différence entre les références de Java et des
pointeurs de C++, parce que la même chose vaut pour les autres
types de base. En Java, les objets ont une adresse, mais non les
variables (ni les éléments d'un objet).
--
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
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.
int i = 1; int* adr_i = &i;
On peut prendre l'adresse de n'importe quelle variable...
On discutait les différences entre les pointeurs de C++ et les références de Java. On ne peut pas prendre l'adresse d'un pointeur en Java (à l'encontre de C++), mais ce n'est pas vraiment une différence entre les références de Java et des pointeurs de C++, parce que la même chose vaut pour les autres types de base. En Java, les objets ont une adresse, mais non les variables (ni les éléments d'un objet).
-- 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
Gabriel Dos Reis
"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 ?
Oui.
-- Gaby
"Vincent Lascaux" <nospam@nospam.org> 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 ?
| 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 ?