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