Comment peut - *i
et u.i
imprimer des numéros différents dans le présent code, même s' i
est défini comme int *i = &u.i;
? Je ne peux que supposer que je suis déclenchement UB ici, mais je ne vois pas comment exactement.
(ideone démo réplique si je sélectionne " C " comme la langue. Mais comme @2501 l'a souligné, pas si "C99 stricte" est la langue. Mais là encore, j'ai eu le problème avec gcc-5.3.0 -std=c99
!)
// gcc -fstrict-aliasing -std=c99 -O2
union
{
int i;
short s;
} u;
int * i = &u.i;
short * s = &u.s;
int main()
{
*i = 2;
*s = 100;
printf(" *i = %d\n", *i); // prints 2
printf("u.i = %d\n", u.i); // prints 100
return 0;
}
(gcc 5.3.0, -fstrict-aliasing -std=c99 -O2
, également avec -std=c11
)
Ma théorie est qu' 100
est la "bonne" réponse, parce que l'écriture pour les membres de l'union à travers l' short
-lvalue *s
est définie en tant que telle (pour cette plate-forme/stockage/whatever). Mais je pense que l'optimiseur ne se rend pas compte que l'écriture d' *s
peut-alias u.i
, et, par conséquent, elle estime que ceux - *i=2;
est la seule ligne qui peut affecter *i
. Est-ce raisonnable de la théorie?
Si *s
peut-alias u.i
, et u.i
peut-alias *i
, alors sûrement que le compilateur doit penser qu' *s
peut-alias *i
? Ne devrait pas aliasing être "transitif'?
Enfin, j'ai toujours eu cette hypothèse que le strict-aliasing problèmes ont été causés par le mauvais casting. Mais il n'y a pas de casting dans ce!
(Mon fond est le C++, j'espère que je me suis poser une question raisonnable sur le C ici. Mon (limitée) de la compréhension, c'est que, en C99, il est acceptable d'écrire grâce à un membre de l'union, puis la lecture par un autre membre d'un type différent.)