Zig Enums and Unions: Tagged Logic

Zig Enums and Unions: Tagged Logic
In your career as a system developer, you will constantly need to represent a "Choice." Whether you are building a network protocol, a compiler, or an operating system kernel, you will encounter scenarios where a piece of data must be one of several discrete types.
- Is the CPU in 'User Mode' or 'Kernel Mode'?
- Is the incoming packet a 'Login Request' or a 'Logout Notification'?
In legacy systems (C/C++), this was handled with ambiguous integers or dangerous "Raw Unions" that could easily crash a system. Zig solves this with Tagged Unions and Exhaustive Enums. This 1,500+ word guide explores how to build memory-efficient, crash-proof logic using Zig’s type-safe choices.
1. Enums: The Type-Safe Label
An enum in Zig is a set of named constants. However, unlike enums in C—which are essentially just "fancy integers"—Zig enums are first-class types.
A. Backing Types and Memory Control
You can specify exactly how much memory an enum uses:
In a large array of $1,000,000$ status codes, using u8 instead of the default i32 saves megabytes of RAM.
B. Enums are "Mini-Types"
Enums can have methods attached to them. This allows you to centralize logic:
C. The "." Shorthand
Zig allows you to omit the name of the enum when it can be inferred by the compiler.
2. The Physics of the Tag: Where is the State Stored?
In a Tagged Union, the "Tag" is the instruction to the CPU: "Which set of fields am I looking at?"
The Memory Mirror
- The Placement: In a standard tagged union, the tag (the enum) is stored at the beginning or end of the structure.
- The Physics: If you define an
enum(u8), the tag takes 1 Byte. However, due to Pointer Alignment, the CPU might insert "Padding" to ensure the following data starts on a 4-byte or 8-byte boundary. - The Optimization: Zig's
@sizeOf()and@alignOf()allow you to see this padding in your hardware map. In high-performance systems, we often usepacked unionto eliminate this padding, squeezing every bit of information into the L1 Cache.
3. Unions: The High-Performance Variant
A union is a specialized data structure that allows multiple fields to share the exact same memory address.
- If you have an
Int(4 bytes) and aFloat(4 bytes) in a union, the total size is only 4 bytes. - The Catch: You can only store ONE of those values at a time.
The Problem with "Raw" Unions
In a raw union, the compiler has no idea which field is currently active. If you save an Int but try to read a Float, the CPU will interpret the integer's bits as a decimal number, leading to garbage data or a system crash. Never use raw unions unless you are performing low-level bit-casts.
3. Tagged Unions: The "Zig Way"
Zig’s primary solution is the Tagged Union. It is a union that automatically carries a "hidden" enum (the tag) to keep track of which field is active.
The Safety Contract
If you attempt to access Message.text while the union is currently holding an id, Zig will:
- Debug Mode: Panic and stop the program safely with a clear error message.
- Release Mode: Treat it as an efficiently optimized choice, relying on the programmer's switch logic.
4. Total Exhaustiveness with Switch
The most professional way to work with Tagged Unions is via the switch statement. Zig forces you to handle every possible state.
Why this is future-proof: If you add a .video field to your Message union next month, every switch statement in your entire codebase will immediately fail to compile. This "Compiler-Lead Refactoring" ensures you never miss an edge case.
5. Memory Efficiency: The Optional Optimization
Did you know that ?*u32 (an optional pointer) is technically a tagged union?
Zig’s compiler perform an optimization where it uses the 0x0 (null) value of the pointer as the "Tag." This means the optional takes zero extra bytes.
You can apply similar logic to your own unions. By choosing your bit-widths wisely, you can create complex data structures that are $2x-4x$ smaller than equivalent structures in Java or Python.
6. Boolean vs. Enum: The Architecture of Branch Predictors
In 2026, we avoid bool for complex state. A bool is a coin flip; an enum is a map.
The Predictor Mirror
- The Process: CPUs are optimized for binary branches (
if true/false). However, a well-definedenumused in aswitchallows the compiler to generate a Jump Table. - The Physics: Instead of the CPU guessing "True or False," it performs a single
JMPto a calculated index in memory. - The Result: For state machines with 3 or more states, an
enumswitch is often faster than a chain ofif/elsebooleans because it reduces the mental load on the CPU’s Speculative Execution engine.
7. Hardware Mapping: Packed Enums and Unions
If you are writing a driver for a network card or an SSD, you need to match the bits defined in a PDF datasheet.
packed enum: Forces the enum to occupy only the necessary bits.packed union: Ensures the fields overlap at exact bit-boundaries.
This allows you to receive a $64$-bit number and instantly read its "parts" without any slow "Bit-Shifting" logic.
7. Real-World Pattern: The Result Union
While Zig has built-in error handling, sometimes you want a complex "Result" that holds rich data about a failure.
This is a common pattern in high-traffic APIs where "Not Found" is a valid business outcome, not an "Exception."
Enums and Unions are the "Logic Switches" of your architecture. By mastering the Tagged Union and the discipline of exhaustive switching, you gain the ability to build complex, branching logic that is both incredibly fast and impossible to break. You graduate from "Managing state" to "Architecting Choices."
Phase 6: Choice Mastery Checklist
- Refactor your raw integers (e.g.,
status: u32) into explicit Enums with backing types. - Upgrade your polymorphism: Replace unsafe void pointers with Tagged Unions.
- Implement Switch Exhaustiveness: Remove
else =>from every enum-based switch to enable compile-time safety. - Optimize memory: Use
@sizeOfto verify if apacked unioncan reduce your data footprint. - Use Payload Capturing (
|val|) to ensure your logic only accesses valid, active memory.
Read next: Functions and Structs: The Logic of Composition →
Part of the Zig Mastery Course — engineering the choice.
