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.

Reply via email to