Skip to content

Instantly share code, notes, and snippets.

@alogic0
Last active May 19, 2026 03:57
Show Gist options
  • Select an option

  • Save alogic0/abd1268647d6725b53d2442af8525f6f to your computer and use it in GitHub Desktop.

Select an option

Save alogic0/abd1268647d6725b53d2442af8525f6f to your computer and use it in GitHub Desktop.
Zig vtables

In Zig, vtables (virtual tables) are a manual pattern used to implement dynamic dispatch, allowing different types to be used through a single, shared interface. 12345 Unlike languages like C++ or Java, Zig does not have "classes" or "interfaces" as built-in keywords. Instead, you construct vtables yourself by creating a struct of function pointers. 678910

How Zig vtables Work

A typical Zig interface is a "fat pointer" consisting of two main parts: 311

  1. A Context Pointer (ptr): A pointer to the specific implementation's data, usually typed as *anyopaque.
  2. A VTable Pointer (vtable): A pointer to a constant struct containing function pointers that define the interface's behavior. 31213

Example: std.mem.Allocator

The most prominent use of this pattern in the Zig Standard Library is the Allocator. It allows functions to accept any allocator (like ArenaAllocator or GeneralPurposeAllocator) without knowing exactly which one is being used at compile time. 389

// Conceptual structure of a Zig VTable
const VTable = struct {
    alloc: *const fn (ctx: *anyopaque, len: usize, ptr_align: u8, ret_addr: usize) Error![]u8,
    resize: *const fn (ctx: *anyopaque, buf: []u8, buf_align: u8, new_len: usize, ret_addr: usize) bool,
    free: *const fn (ctx: *anyopaque, buf: []u8, buf_align: u8, ret_addr: usize) void,
};

Key Characteristics

  • Explicit over Implicit: You must manually define the vtable struct and the "wrapper" interface struct. There is no hidden "vptr" added to your data structs by the compiler.
  • Comptime Known: Most vtables in Zig are created as const anonymous structs, which the compiler often places in read-only memory.
  • Performance Trade-off: Using a vtable introduces a "lookup indirection" (the CPU must follow a pointer to find the function), which is slightly slower than direct function calls and can hinder some compiler optimizations like inlining.
  • Alternative (anytype): For better performance, Zig developers often prefer Static Dispatch using anytype or comptime generics, which resolves the call at compile time and allows for full inlining. 13411131415

Footnotes

  1. https://ziggit.dev 2

  2. https://williamw520.github.io

  3. https://www.reddit.com 2 3 4 5

  4. https://finance.biggo.com 2

  5. https://github.com

  6. https://news.ycombinator.com

  7. https://www.youtube.com

  8. https://www.openmymind.net 2

  9. https://twdev.blog 2

  10. https://www.openmymind.net

  11. https://www.reddit.com 2

  12. https://williamw520.github.io

  13. https://ziggit.dev 2

  14. https://www.geeksforgeeks.org

  15. https://ziggit.dev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment