> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C++ Union

A union is a user-defined data type in which all members share the same memory location. Unlike a `struct` or `class` where each member has its own distinct memory address, a union allocates only enough memory to hold its largest member, and its overall alignment is determined by the member with the strictest alignment requirement. Consequently, a union can store a valid value for only one of its non-static data members at any given time.

```cpp theme={"dark"}
union UnionName {
    type1 member1;
    type2 member2;
    type3 member3;
};
```

## Memory Layout

The `sizeof` a union is equal to the size of its largest data member, potentially padded to satisfy the alignment requirements of the overall union.

```cpp theme={"dark"}
union Data {
    char c;      // 1 byte
    int i;       // 4 bytes
    double d;    // 8 bytes
};
// sizeof(Data) is 8 bytes.
// All members start at the exact same memory address.
```

## The Active Member and Undefined Behavior

In C++, the member that was most recently written to is known as the **active member**. Reading from a member other than the active member results in Undefined Behavior (UB). C++ strictly forbids using unions for type punning (interpreting the bit representation of one type as another type), which is a notable divergence from C.

```cpp theme={"dark"}
Data data;
data.i = 42;          // 'i' becomes the active member
int val = data.i;     // Valid: reading the active member

// double bad = data.d; // UNDEFINED BEHAVIOR: 'd' is not the active member
```

## Anonymous Unions

An anonymous union is a union defined without a type name and without declaring an object of that type. The members of an anonymous union are injected directly into the enclosing scope and are accessed as if they were direct variables of that scope. If an anonymous union is declared at namespace scope (global scope), it must be explicitly declared `static`.

```cpp theme={"dark"}
static union {        // Namespace scope anonymous union must be static
    int global_int;
    float global_float;
};

struct Token {
    int token_type;
    union {           // Anonymous union at class scope
        int int_val;
        float float_val;
    };
};

Token t;
t.token_type = 1;
t.int_val = 100;      // Accessed directly, no union variable name required
```

## Unrestricted Unions (C++11)

Prior to C++11, unions were restricted to Plain Old Data (POD) types. They could not contain members with non-trivial constructors, destructors, copy constructors, or assignment operators (e.g., `std::string` or `std::vector`).

C++11 introduced **unrestricted unions**, allowing members with non-trivial special member functions. However, if a union contains a non-trivial member, the compiler implicitly deletes the union's corresponding default special member functions (constructor, destructor, etc.). The developer assumes full responsibility for managing the object lifecycle using **placement new** to construct the active member and **explicit destructor calls** to destroy it.

```cpp theme={"dark"}
#include <string>
#include <new>

union UnrestrictedData {
    int i;
    std::string s; // Non-trivial member

    // Default constructor and destructor must be explicitly defined
    // because the inclusion of std::string causes them to be implicitly deleted.
    UnrestrictedData() {} 
    ~UnrestrictedData() {} 
};

int main() {
    UnrestrictedData ud;
    
    // Constructing the non-trivial member requires placement new
    new (&ud.s) std::string("Hello World"); 
    
    // Destroying the non-trivial member requires an explicit destructor call
    using std::string;
    ud.s.~string(); 
    
    // Switching the active member to a trivial type
    ud.i = 42; 
    
    return 0;
}
```

## `std::variant` (C++17)

Because managing the lifecycle of non-trivial members in unrestricted unions is highly error-prone, C++17 introduced `std::variant`. It is the standard, type-safe alternative to raw unions. `std::variant` automatically manages the construction and destruction of its active member, tracks which type is currently active, and prevents undefined behavior by throwing an exception (`std::bad_variant_access`) on invalid accesses.

```cpp theme={"dark"}
#include <variant>
#include <string>

// std::variant automatically handles memory and lifecycle management
std::variant<int, std::string> safe_data;

safe_data = "Hello World"; // Safely constructs std::string
safe_data = 42;            // Safely destroys std::string, constructs int
```

## Access Control and Member Functions

Like classes and structs, unions can have access specifiers (`public`, `private`, `protected`), member functions, constructors, and destructors. By default, all members of a union are `public`. However, unions have several fundamental restrictions:

* They cannot contain reference members.
* They cannot inherit from other classes.
* They cannot be used as base classes.
* They cannot contain `virtual` functions.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C++ Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
