GNT sans publicité, site mobile, fonctionnalitées exclusives...

Affectation et opérateurs logiques

Le
Romuald
Bonjour,

L'autre jour j'ai pu écrire, en pensant que c'était tout à fait lég=
al,
quelque chose comme :

v = a + (p != NULL) ? 0 : 1;

J'ai été surpris de voir que le résultat n'était pas celui que
j'attendais. Je me suis mis à chercher (dans la norme C99) où était l=
e
comportement indéfini là-dedans et je pense l'avoir trouvé :

A propos de l'affectation : "The side effect of updating the stored
value of the left operand shall
occur between the previous and the next sequence point." et "If an
attempt is made to modify
the result of an assignment operator or to access it after the next
sequence point, the
behavior is undefined."
Sachant que, à propos de l'opérateur ternaire : "The first operand is
evaluated; there is a sequence point after its evaluation.".

Après l'évaluation de "p != NULL" l'affectation n'est pas terminée =
et
pourtant c'est là le "sequence point" suivant, d'où le comportement
indéfini.

Je pense que j'ai bon ?

Vu comment les opérateurs de comparaison && et || fonctionnent ça
voudrait dire qu'on ne peux pas affecter à une variable le résultat de
ces opérateurs ? Tout porte à le croire mais j'ai du mal à comprendre
pourquoi le langage l'interdirait* ?

Merci d'avance !

* Ok, c'est juste "comportement indéfini", c'est pas "interdit", mais
on se comprend !
Lire les 26 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 6
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
espie
Le #23041441
In article Romuald
Bonjour,

L'autre jour j'ai pu écrire, en pensant que c'était tout à fait légal,
quelque chose comme :

v = a + (p != NULL) ? 0 : 1;

J'ai été surpris de voir que le résultat n'était pas celui que
j'attendais. Je me suis mis à chercher (dans la norme C99) où était le
comportement indéfini là-dedans et je pense l'avoir trouvé :



Sans contexte, ca va etre un peu dur. C'est quoi les declarations de
v, a, p dans ton programme ?

Et d'ou sort NULL ? c'est le NULL des entetes standards, ou un NULL que
tu as defini tout seul ?
Romuald
Le #23041561
On 21 jan, 18:34, (Marc Espie) wrote:
Sans contexte, ca va etre un peu dur. C'est quoi les declarations de
v, a, p   dans ton programme ?

Et d'ou sort NULL ? c'est le NULL des entetes standards, ou un NULL que
tu as defini tout seul ?



Voilà un programme complet :

#include
int main(void) {
int v;
int a = 1;
int* p = NULL;

v = a + (p != NULL) ? 0 : 1;

printf("%dn", v);

return 0;
}

(J'ai compile avec GCC 4.4.3)

J'avais donne aucune info de ce genre car comme on peut le voir ça va
pas chercher aussi loin que d'aller definir son propre NULL :-).
Le probleme me semble independant des types qu'on donne, c'est juste
l'utilisation de l'operateur ternaire la au milieu.
Pierre Maurette
Le #23041661
Romuald, le 1/21/2011 a écrit :
On 21 jan, 18:34, (Marc Espie) wrote:
Sans contexte, ca va etre un peu dur. C'est quoi les declarations de
v, a, p   dans ton programme ?

Et d'ou sort NULL ? c'est le NULL des entetes standards, ou un NULL que
tu as defini tout seul ?



Voilà un programme complet :

#include
int main(void) {
int v;
int a = 1;
int* p = NULL;

v = a + (p != NULL) ? 0 : 1;

printf("%dn", v);

return 0;
}

(J'ai compile avec GCC 4.4.3)

J'avais donne aucune info de ce genre car comme on peut le voir ça va
pas chercher aussi loin que d'aller definir son propre NULL :-).
Le probleme me semble independant des types qu'on donne, c'est juste
l'utilisation de l'operateur ternaire la au milieu.



Je vous suggère de placer des parenthèses pour forcer l'associativité
que vous souhaitez. Là, c'est (a + (p != NULL)) ? 0 : 1) donc ça vaut
toujours 0 sauf pour a == 0 où ça vaut 1.
Il y a une façon plus simple d'écrire ça.

--
Pierre Maurette
Romuald
Le #23041711
On 21 jan, 19:02, Pierre Maurette

Je vous sugg re de placer des parenth ses pour forcer l'associativit
que vous souhaitez. L , c'est (a + (p != NULL)) ? 0 : 1) donc a vaut
toujours 0 sauf pour a == 0 o a vaut 1.
Il y a une fa on plus simple d' crire a.




En effet j'avais pas remarque ça.
J'ai donc voulu dire "a + ((p != NULL) ? 0 : 1)".
Cependant dans les deux cas le probleme du "sequence point" se pose
toujours, non ?
Pierre Maurette
Le #23041731
Romuald, le 1/21/2011 a écrit :
On 21 jan, 19:02, Pierre Maurette

Je vous sugg re de placer des parenth ses pour forcer l'associativit
que vous souhaitez. L , c'est (a + (p != NULL)) ? 0 : 1) donc a vaut
toujours 0 sauf pour a == 0 o a vaut 1.
Il y a une fa on plus simple d' crire a.




En effet j'avais pas remarque ça.
J'ai donc voulu dire "a + ((p != NULL) ? 0 : 1)".
Cependant dans les deux cas le probleme du "sequence point" se pose
toujours, non ?



Non, avec mon gcc qui est au feu, en -stdÉ9, vite fait, ça fait ce
que j'attends. Notez que si a est un int et p un pointeur, votre truc
se remplace par "a + !p".

--
Pierre Maurette
Publicité
Suivre les réponses
Poster une réponse
Anonyme