Advanced 13 min

Union and Enum

Master enumerations for type-safe constants and unions for memory-efficient data

Learn how to use enumerations for type-safe named constants and unions for memory-efficient storage of multiple types.

A Simple Example

#include <iostream>
#include <string>

enum class Color {
    Red,
    Green,
    Blue
};

enum class Status {
    Success,
    Error,
    Pending
};

union Data {
    int intValue;
    float floatValue;
    char charValue;
};

int main() {
    Color color{Color::Red};

    if (color == Color::Red) {
        std::cout << "Color is red\n";
    }

    // Can't accidentally compare different enums
    // if (color == Status::Success) {} // ERROR!

    Data data;
    data.intValue = 42;
    std::cout << "Int: " << data.intValue << "\n";

    data.floatValue = 3.14f;  // Overwrites intValue
    std::cout << "Float: " << data.floatValue << "\n";

    return 0;
}

Breaking It Down

enum class - Modern Enumerations

  • What it does: Creates a type-safe named constant group
  • Syntax: enum class Name { Value1, Value2, Value3 };
  • Access: Must use scope: Name::Value1 (prevents pollution)
  • Remember: Can't accidentally compare different enum types

Old-Style enum vs enum class

  • Old enum: Values pollute namespace, implicit int conversion
  • enum class: Scoped values, no implicit conversions (safer)
  • Modern C++ prefers enum class for type safety
  • Remember: Use enum class unless you need backward compatibility

union - Shared Memory Storage

  • What it does: All members share the same memory location
  • Size: Equal to the largest member
  • Only one member is valid at a time
  • Remember: Writing to one member overwrites the others

When to Use Unions

  • Memory-constrained systems: Saves space when only one variant is needed
  • Type punning: Reinterpreting data (advanced, be careful)
  • Network protocols: Different interpretations of the same bytes
  • Remember: Modern C++ often prefers std::variant for type-safe unions

Why This Matters

  • Magic numbers like if (status == 2) are unclear and error-prone. Enums give names to values: if (status == Status::Success).
  • Modern enum class prevents namespace pollution and accidental conversions, making code safer and more maintainable.
  • Unions let multiple types share memory - useful for parsers, network protocols, and memory-constrained systems.
  • Understanding these features helps you write clearer, safer, and more efficient code.

Critical Insight

Enums replace magic numbers with meaningful names. Instead of if (response == 200), you write if (response == HttpStatus::OK). The code becomes self-documenting!

Unions are like a hotel room - multiple guests can book it, but only one can stay at a time. All union members share the same memory address, so writing to one overwrites the others. This saves memory but requires careful tracking of which member is currently valid.

Best Practices

Prefer enum class over old-style enum: Modern C++ code should use enum class for better type safety and scoped values.

Give enums meaningful names: Use descriptive names like HttpStatus, ConnectionState, or ErrorCode instead of generic names.

Track which union member is active: Keep a separate variable to remember which union member was last written to.

Consider std::variant instead of unions: For type-safe alternatives to unions, use std::variant from modern C++.

Common Mistakes

Forgetting scope for enum class: Must use Status::Success, not just Success. The scope prevents namespace pollution.

Reading wrong union member: Reading a union member that wasn't the last one written leads to undefined behavior.

Assuming unions have multiple valid values: Only the last written member is valid at any time in a union.

Using unions with non-trivial types: Unions can't directly contain types with constructors/destructors. Use std::variant instead.

Debug Challenge

This code tries to access an enum value. Click the highlighted line to fix it:

1 #include <iostream>
2
3 enum class Status {
4 Success,
5 Error
6 };
7
8 int main() {
9 Status s{Success};
10 return 0;
11 }

Quick Quiz

  1. What is the main advantage of enum class over old-style enum?
Type safety and scoped values
Better performance
Smaller memory footprint
  1. What happens when you write to a union member?
It overwrites all other members
It only affects that member
Compiler error
  1. How do you access an enum class value?
EnumName::Value
Value
enum::Value

Practice Playground

Time to try out what you just learned! Play with the example code below, experiment by making changes and running the code to deepen your understanding.

Lesson Progress

  • Fix This Code
  • Quick Quiz
  • Practice Playground - run once