Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing same-type inactive member in unions

I have something like this:

union DataXYZ
{
    struct complex_t
    {
        float real, imag;
    } complex;

    struct vector_t
    {
        float magnitude, phase;
    } vector;
};

I have some vectors of these, being general-purpose workspace memory, where I use the fields accordingly after the semantic context.

I know it's undefined behaviour to read a field in a union, when the last active member was another field (and type?). Does this matter when the types and layout match exactly?

I've been commenting on some other similar questions, asking for references that guarantee the behaviour, but nothing came up yet - hence this question.

like image 250
Shaggi Avatar asked Jan 08 '16 12:01

Shaggi


People also ask

Can union have static members?

In C++ union can contain static members which, as in the case of classes, belong to a class and therefore are common to all objects.

What are the restrictions that must be observed when using C++ unions?

A union cannot have base classes and cannot be used as a base class. A union cannot have non-static data members of reference types. Unions cannot contain a non-static data member with a non-trivial special member function (copy constructor, copy-assignment operator, or destructor).

What is union Data Type C++?

In C++17 and later, the std::variant class is a type-safe alternative for a union. A union is a user-defined type in which all members share the same memory location. This definition means that at any given time, a union can contain no more than one object from its list of members.

How do C++ unions work?

Purpose of Unions in C/ C++ Union is a user-defined datatype. All the members of union share same memory location. Size of union is decided by the size of largest member of union. If you want to use same memory location for two or more members, union is the best for that.


1 Answers

Yes you can read the other member in this particular case.

This is what the C++11/14 standard has to say:

9.5 - Unions

In a union, at most one of the non-static data members can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time.

But the note immediately after the section makes your particular instance legal since one special guarantee is made in order to simplify the use of unions:

[ Note: If a standard-layout union contains several standard-layout structs that share a common initial sequence (9.2), and if an object of this standard-layout union type contains one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of standard-layout struct members; see 9.2. —end note ]

And your structs do share a common initial sequence:

9.2.16 - Class members

The common initial sequence of two standard-layout struct (Clause 9) types is the longest sequence of non- static data members and bit-fields in declaration order, starting with the first such entity in each of the structs, such that corresponding entities have layout-compatible types and either neither entity is a bit-field or both are bit-fields with the same width.

like image 133
4 revs, 2 users 73% Avatar answered Sep 28 '22 17:09

4 revs, 2 users 73%