-1

According to this and this active member of union doesn't imply any actions by the language/compiler. We must ourselves must make sure that the members are activated/deactivated correctly i.e. by calling their constructor/destructor.

With that in mind, it should be safe to have all members active (its currently working like this, no assignments are made at all), but I wonder if I used undefined behavior at some point (because I definitely don't use the return value of placement new which must be done (or std::launder) in order to avoid issues through the optimizer)

/// not really a union 
/// just a handy way to access the individual elements named 
/// and still be able to iterate over them, 
/// thus \see bucket and \see buckets are always both active
union Buckets
{
    using Type = std::map<int,char>;

    struct
    {
        Type    a;
        Type    b;
        Type    c;
        Type    d;
        Type    e;
        Type    f;
    }       bucket;
    Type    buckets[6];

    static_assert(sizeof(bucket) == sizeof(buckets));
    Buckets()  { for (auto& current : buckets) new(&current) Type(); }
    ~Buckets() { for (auto& current : buckets) current.~Type(); }
};
Akshay Anurag
  • 724
  • 1
  • 8
  • 27
rob
  • 11
  • 4

4 Answers4

3

You can't have all union members "active".

Only the last written-to member is active.

Any attempt to read from some other member leads to undefined behavior.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • sure I can, the code does _work_ (maybe by using undefined behaviour) – rob Nov 13 '19 at 14:20
  • @rob If you have [undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior) then the code doesn't "work", it just *seems* like that. It can stop "working" when you least expect it. It can cause your hard-drive to be formatted, or crash your program, or it can even summon [nasal demons](http://www.catb.org/jargon/html/N/nasal-demons.html). – Some programmer dude Nov 13 '19 at 15:07
2

It is not possible to have all members of union active (simultaneously). Only one member is ever active at any moment. If you activate another member without deactivating the previous correctly (by calling destructor if needed), then that previously active member is deactivated incorrectly, rather than left active.

If you want all members to be active, then you need a non-union class.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

Certainly it is save to have all members of a union active.

Just remember that only the last one written to is, and thus the above is not all that interesting, as it only applies to unions with zero or one member.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • this is rather picky because it just explains that the term _all_ includes zero or one element (which is definitely more precise then my question, which should have using _many_ or _multiple_ in first place) – rob Nov 13 '19 at 14:24
0

https://en.cppreference.com/w/cpp/language/data_members#Standard_layout tells that it is fine to do so, at least since C++14

In a standard-layout union with an active member of non-union class type T1, it is permitted to read a non-static data member m of another union member of non-union class type T2 provided m is part of the common initial sequence of T1 and T2 (except that reading a volatile member through non-volatile glvalue is undefined).

since in the current case T1 and T2 donate the same type anyway.

rob
  • 11
  • 4