On 01/03/2010 10:14 PM, Joshua Haberman wrote: > Andrew Haley <aph <at> redhat.com> writes: >> On 01/03/2010 10:53 AM, Richard Guenther wrote: >>> GCC follows its own documentation here, not some random >>> websites and maybe not the strict reading of the standard. >> >> GCC is compatible with C99 in this regard. > > I do not believe this is true. Your argument that GCC complies with C99 > (which you moved to gcc-help@)
It's not appropriate here. However, since we've started... > is based on the argument that these are > not compatible types: > > union u { int x; } > int x; > > However, I did not claim that they are compatible types, nor does my > argument rely on them being compatible types. Rather, my argument is > based on section 6.5, paragraph 7 of C99, which I quoted, which > specifies the circumstances under which an object may or may not be > aliased. The case of compatible types is one case, but not the only > case, in which values may be aliased according to the standard. "An object shall have its stored value accessed only by an lvalue expression that has one of the following types: ... an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or ..." doesn't mean that you can get such an aggregate or union lvalue by union u { int x; } *pu = (union u*)&i; because the rules about pointer conversions only allow the result of (union u*)&i to be converted back to an (int*). They do not allow you to dereference that pointer as a (union u*): "6.3.2.3 "A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer." This is *all* you are allowed to do with the converted pointer. You may not dereference it. This is the core rule that governs C's aliasing. Andrew.