Search code examples
c++structunions

Are anonymous unions acceptable for aliasing member variables in a struct?


Let's say that I have the following C++ code:

struct something
{
  // ...
  union { int size, length; };
  // ...
};

This would create two members of the struct which access the same value: size and length.

Would treating the two members as complete aliases (i.e. setting the size, then accessing the length and vice/versa) be undefined behaviour? Is there a "better" way to implement this type of behaviour, or is this an acceptable implementation?


Solution

  • Yes, this is allowed and well-defined. According to §3.10 [basic.lval]:

    10/ If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:

    — the dynamic type of the object

    [...]

    Since here we store an int and read through an int, we access the object through a glvalue of the same dynamic type than the object, thus things are fine.


    There even is a special caveat in the Standard for structures that share the same prefix. Or, in standardese, standard-layout types that share a common initial sequence.

    §9.2/18 If a standard-layout union contains two or more standard-layout structs that share a common initial sequence, and if the standard-layout union object currently contains one of these standard-layout structs, it is permitted to inspect the common initial part of any of them. Two standard-layout structs share a common initial sequence if corresponding members have layout-compatible types and either neither member is a bit-field or both are bit-fields with the same width for a sequence of one or more initial members.

    That is:

    struct A { unsigned size; char type; };
    struct B { unsigned length; unsigned capacity; };
    
    union { A a; B b; } x;
    
    assert(x.a.size == x.b.length);
    

    EDIT: Given that int is not a struct (nor a class) I am afraid it's actually not formally defined (I certainly could not see anything in the Standard), but should be safe in practice... I've brought the matters to the isocpp forums; you might have found a hole.

    EDIT: Following the above mentionned discussion, I have been shown §3.10/10.