#include <iostream>
#include <cstdint>
union S
{
std::int32_t n; // occupies 4 bytes
std::uint16_t s[2]; // occupies 4 bytes
std::uint8_t c; // occupies 1 byte
}; // the whole union occupies 4 bytes
int main()
{
S s = {0x12345678}; // initializes the first member, s.n is now the active member
// at this point, reading from s.s or s.c is undefined behavior
std::cout << std::hex << "s.n = " << s.n << '
';
s.s[0] = 0x0011; // s.s is now the active member
// at this point, reading from n or c is UB but most compilers define it
std::cout << "s.c is now " << +s.c << '
' // 11 or 00, depending on platform
<< "s.n is now " << s.n << '
'; // 12340011 or 00115678
}
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.
It also means that no matter how many members a union has, it always uses only enough memory to store the largest member.
A union can be useful for conserving memory when you have lots of objects and limited memory.
However, a union requires extra care to use correctly.
You're responsible for ensuring that you always access the same member you
assigned. If any member types have a non-trivial constructor, then you must
write additional code to explicitly construct and destroy that member.
Before you use a union, consider whether the problem
you're trying to solve could be better expressed by using a
base class and derived class types.