On 1/25/06, Alexandre Oliva <[EMAIL PROTECTED]> wrote: > On Jan 22, 2006, Richard Guenther <[EMAIL PROTECTED]> wrote: > > > On 1/22/06, Alexandre Oliva <[EMAIL PROTECTED]> wrote: > >> I don't think it is any different. GCC's exception for unions only > >> applies if the object is accessed using the union type. So they are > >> indeed equivalent. The scary thing is that I don't think they > >> actually violate the ISO C strict aliasing rules, but they might still > >> be mis-optimized by GCC, assuming I understand correctly what GCC > >> does. > > > ISO C says that the following violates aliasing rules: > > > int foo(float f) { union { int i; float f; } u; i.f = f; return i.i; } > > Yes, but this was not what the example I quoted from Richard Sandiford > was about. The example only accessed a memory region using its > effective type: > > > int ii; double dd; void foo (int *ip, double *dp) { > > *ip = 15; ii = *ip; *dp = 1.5; dd = *dp; } > > void test (void) { union { int i; double d; } u; > > foo (&u.i, &u.d); } > > So it is perfectly valid, but if GCC reorders the read from *ip past > the store to *dp, it turns the valid program into one that misbehaves.
*ip = 15; ii = *ip; *dp = 1.5; dd = *dp; Here ^^^ you are accessing memory of type integer as type double. And gcc will happily reorder the read from *ip with the store to *dp based on TBAA unless it inlines the function and applies the "special" gcc rules about unions. So this example is invalid, too. > Unless the undefined behavior is taking the address of both u.i and > u.d, when only one of them is well-defined at that point. I don't > think taking the address of a member of a union counts as accessing > the stored value of the object, since if the member is volatile, a > read from memory is not expected. Taking the address does not count as access, but dereferencing it may violate aliasing rules. Richard.