In ISO C99 6.5.2.3 paragraph 5, it is mentioned that:

``One special guarantee is made in order to simplify the use of unions: if a
union contains several structures that share a common initial sequence (see
below), and if the union object currently contains one of these structures, it
is permitted to inspect the common initial part of any of them anywhere that a
declaration of the complete type of the union is visible.''

The code in the two files below shows that function "f" is over-optimized (when
compiled with -O3) w.r.t (my reading of) the above paragraph.  Putting the
definition of "f" right after main does not show the problem (perhaps due to
overall constant propagation and inlining).  The problem is also prevented by
telling -fno-strict-aliasing to gcc, but IMO the code is conforming to ISO C99
and should not need this flag to compile properly.

// file prog.c
typedef struct A { int i; int j; double d; } A;
typedef struct B { int i; int j; char *pc; } B;
typedef union U { A a; B b; } U;

extern int f(A *, B *);

int main(void)
{
  U u = { { 1, 1, 0 } };
  return f(&u.a, &u.b);
}

// file f.c
typedef struct A { int i; int j; double d; } A;
typedef struct B { int i; int j; char *pc; } B;
typedef union U { A a; B b; } U; // union visible before definition of f

extern int f(A *, B *);

int f(A *pa, B *pb)
{
  pa->j += 2;
  pb->j += 3;  // hence, this should be known as a possible alias for pa->j
  return pa->j;
}

// Compilation (no warnings issued)
gcc -Wall -Wextra --std=gnu99 -O3 prog.c f.c -o prog

// Expected return value: 6
// gcc-4.4.1 -O3: 3
// gcc-4.4.1 -O3 -fno-strict-aliasing: 6
// gcc-4.4.1 all code in one file: 6
// gcc-3.4.6: 6

Regards,
--
Daniel Villeneuve
Kronos


-- 
           Summary: accessing a field via two pointers to structures that
                    share a common prefix
           Product: gcc
           Version: 4.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: dvilleneuve at kronos dot com
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42432

Reply via email to