Responses to other answers with a warning about section 6.5.2.3. There seems to be some debate about the exact wording anywhere that a declaration of the completed type of the union is visible , and at least GCC does not implement it as written . There are several tangential CR defects reports here and here , followed by comments from the committee.
I recently tried to figure out how other compilers (in particular, GCC 4.8.2, ICC 14, and clang 3.4) interpret this using the following code from the standard:
// Undefined, result could (realistically) be either -1 or 1 struct t1 { int m; } s1; struct t2 { int m; } s2; int f(struct t1 *p1, struct t2 *p2) { if (p1->m < 0) p2->m = -p2->m; return p1->m; } int g() { union { struct t1 s1; struct t2 s2; } u; u.s1.m = -1; return f(&u.s1,&u.s2); }
GCC: -1, clang: -1, ICC: 1 and warns of aliases
// Global union declaration, result should be 1 according to a literal reading of 6.5.2.3/6 struct t1 { int m; } s1; struct t2 { int m; } s2; union u { struct t1 s1; struct t2 s2; }; int f(struct t1 *p1, struct t2 *p2) { if (p1->m < 0) p2->m = -p2->m; return p1->m; } int g() { union uu; u.s1.m = -1; return f(&u.s1,&u.s2); }
GCC: -1, clang: -1, ICC: 1, but warns of aliases
// Global union definition, result should be 1 as well. struct t1 { int m; } s1; struct t2 { int m; } s2; union u { struct t1 s1; struct t2 s2; } u; int f(struct t1 *p1, struct t2 *p2) { if (p1->m < 0) p2->m = -p2->m; return p1->m; } int g() { u.s1.m = -1; return f(&u.s1,&u.s2); }
GCC: -1, clang: -1, ICC: 1, without warning
Of course, without rigorous smoothing optimization, all three compilers return the expected result each time. Since clang and gcc have no outstanding results in any of the cases, the only real information comes from the lack of ICC diagnostics in the latter. This is also consistent with the example given by the standards committee in the first defect report mentioned above.
In other words, this aspect of C is a real minefield, and you need to be careful that your compiler does the right thing, even if you follow the writing standard. All the worse, because it is intuitively clear that such a pair of structures must be compatible in memory.