gcc, strict-aliasing, and casting through a union
- by Joseph Quinsey
About a year ago the following paragraph was added to the GCC Manual, version 4.3.4, regarding -fstrict-aliasing:
Similarly, access by taking the address, casting the resulting pointer and dereferencing the result has undefined behavior [emphasis added], even if the cast uses a union type, e.g.:
union a_union {
int i;
double d;
};
int f() {
double d = 3.0;
return ((union a_union *)&d)->i;
}
Does anyone have an example to illustrate this undefined behavior?
Note this question is not about what the C99 standard says, or does not say. It is about the actual functioning of gcc, and other existing compilers, today.
My simple, naive, attempt fails. For example:
#include <stdio.h>
union a_union {
int i;
double d;
};
int f1(void) {
union a_union t;
t.d = 3333333.0;
return t.i; // gcc manual: 'type-punning is allowed, provided ...'
}
int f2(void) {
double d = 3333333.0;
return ((union a_union *)&d)->i; // gcc manual: 'undefined behavior'
}
int main(void) {
printf("%d\n", f1());
printf("%d\n", f2());
return 0;
}
works fine, giving on CYGWIN:
-2147483648
-2147483648
Also note that taking addresses is obviously wrong (or right, if you are trying to illustrate undefined behavior). For example, just as we know this is wrong:
extern void foo(int *, double *);
union a_union t;
t.d = 3.0;
foo(&t.i, &t.d); // UD behavior
so is this wrong:
extern void foo(int *, double *);
double d = 3.0;
foo(&((union a_union *)&d)->i, &d); // UD behavior
For background discussion about this, see for example:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1422.pdf
http://gcc.gnu.org/ml/gcc/2010-01/msg00013.html
http://davmac.wordpress.com/2010/02/26/c99-revisited/
http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule
http://stackoverflow.com/questions/2771023/c99-strict-aliasing-rules-in-c-gcc/2771041#2771041
The first link, draft minutes of an ISO meeting seven months ago, notes in section 4.16:
Is there anybody that thinks the rules are clear enough? No one is really able to interpret tham.