union U { int i; float f; std::string s; };
union A { int x; int y[4]; }; struct B { A a; }; union C { B b; int k; }; int f() { C c; // does not start lifetime of any union member c.b.a.y[3] = 4; // OK: S(c.b.a.y[3]) contains c.b and c.b.a.y; // creates objects to hold union members c.b and c.b.a.y return c.b.a.y[3]; // OK: c.b.a.y refers to newly created object (see [basic.life]) } struct X { const int a; int b; }; union Y { X x; int k; }; void g() { Y y = { { 1, 2 } }; // OK, y.x is active union member ([class.mem]) int n = y.x.a; y.k = 4; // OK: ends lifetime of y.x, y.k is active member of union y.x.b = n; // undefined behavior: y.x.b modified outside its lifetime, // S(y.x.b) is empty because X's default constructor is deleted, // so union member y.x's lifetime does not implicitly start }— end example
u.m.~M(); new (&u.n) N;— end example
union { member-specification } ;is called an anonymous union; it defines an unnamed type and an unnamed object of that type called an anonymous union object.
void f() { union { int aa; char* p; } obj, *ptr = &obj; aa = 1; // error ptr->aa = 1; // OK }
union U { int x = 0; union { int k; }; union { int z; int y = 1; // error: initialization for second variant member of U }; };— end example