Zeenobit
Zeenobit

Reputation: 5204

Unions used like Classes/Structs

I was trying to learn more about unions and their usefulness, when I was surprised that the following code is perfectly valid and works exactly as expected:

template <class T>
union Foo
{
    T a;
    float b;

    Foo(const T& value)
        : a(value)
    {
    }

    Foo(float f)
        : b(f)
    {
    }

    void bar()
    {
    }

    ~Foo()
    {
    }
};

int main(int argc, char* argv[])
{
    Foo<int> foo1(12.0f);
    Foo<int> foo2((int) 12);

    foo1.bar();
    foo2.bar();

    int s = sizeof(foo1); // s = 4, correct

    return 0;
}

Until now, I had no idea that it is legal to declare unions with templates, constructors, destructor, and even member functions. In case it's relevant, I'm using Visual Studio 2012.

When I searched the internet to find more about using unions in this manner, I found nothing. Is this a new feature of C++, or something specific to MSVC? If not, I'd like to learn more about unions, specifically examples of them used like classes (above). If someone could point me to a more detailed explanation of unions and their usage as data structures, it'd be much appreciated.

Upvotes: 4

Views: 328

Answers (1)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158629

Is this a new feature of C++, or something specific to MSVC?

No, as BoBtFish said, the 2003 C++ standard section 9.5 Unions paragraph 1 says:

[...] A union can have member functions (including constructors and destructors), but not virtual (10.3) functions. A union shall not have base classes. A union shall not be used as a base class. An object of a class with a non-trivial constructor (12.1), a non-trivial copy constructor (12.8), a non-trivial destructor (12.4), or a non-trivial copy assignment operator (13.5.3, 12.8) cannot be a member of a union, nor can an array of such objects. If a union contains a static data member, or a member of reference type, the program is ill-formed.

unions do come under section 9 Classes and the grammar for class-key is as follows:

class-key:
   class
   struct
   union

So acts like a class but has many more restrictions. The key restriction being that unions can only have one active non-static member at a time, which is also covered in paragraph 1:

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. [...]

The wording in the C++11 draft standard is similar so it has not changed too much since 2003.

As for the use of a union, there are two common reasons which are covered from different angles in this previous thread C/C++: When would anyone use a union? Is it basically a remnant from the C only days? to summarize:

This answer to Unions cannot be used as Base class gives some really great insight into why unions are implemented as they are in C++.

Upvotes: 2

Related Questions