Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does C standard say about a union of two identical types

Tags:

c

types

unions

Is it possible to to have the following assert fail with any compiler on any architecture?

union { int x; int y; } u;
u.x = 19;
assert(u.x == u.y);
like image 259
perreal Avatar asked Nov 07 '13 14:11

perreal


2 Answers

C99 Makes a special guarantee for a case when two members of a union are structures that share an initial sequence of fields:

struct X {int a; /* other fields may follow */ };
struct Y {int a; /* other fields may follow */ };
union {X x; Y y;} u;
u.x.a = 19;
assert(u.x.a == u.y.a); // Guaranteed never to fail by 6.5.2.3-5.

6.5.2.3-5 : 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. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.

However, I was unable to find a comparable guarantee for non-structured types inside a union. This may very well be an omission, though: if the standard goes some length to describe what must happen with structured types that are not even the same, it should have clarified the same point for simpler, non-structured types.

like image 90
Sergey Kalinichenko Avatar answered Sep 21 '22 13:09

Sergey Kalinichenko


The assert in the problem will never fail in an implementation of standard C because accessing u.y after an assignment to u.x is required to reinterpret the bytes of u.x as the type of u.y. Since the types are the same, the reinterpretation produces the same value.

This requirement is noted in C 2011 (N1570) 6.5.2.3 note 95, which indicates it derives from clause 6.2.6, which covers the representations of types. Note 95 says:

If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called ‘‘type punning’’). This might be a trap representation.

(N1570 is an unofficial draft but is readily available on the net.)

like image 20
Eric Postpischil Avatar answered Sep 22 '22 13:09

Eric Postpischil