RC RANDOM CHAOS

Cracking Open Rust's dyn Trait: A Hands-On Tour of Vtables and Wide Pointers

· via Hacker News

Original source

Visualizing Rust's Vtables: How dyn Trait Works In Memory

Hacker News →

A developer coming to Rust from C++ dissects how the language implements polymorphism, contrasting static dispatch (generics/monomorphization) with dynamic dispatch (dyn Trait). With generics, the compiler stamps out a specialized copy of a function for each concrete type, yielding zero runtime overhead but requiring all types to be known at compile time — Rust’s cleaner answer to C++ patterns like virtual functions and CRTP. The key philosophical difference: C++ templates accept any type with a matching method implicitly, while Rust forces you to spell out the contract by implementing a trait.

The post digs into two memory-level surprises. First, empty structs are zero-sized types (ZSTs) that occupy no memory, because Rust tracks value identity through ownership and the borrow checker rather than through distinct addresses — a break from C++‘s rule that every object is at least one byte. Taking the address of a ZST appears to yield distinct locations in debug builds, but that’s just a debugger convenience; in release mode the addresses collapse, and the compiler guarantees nothing about them.

Second, dynamic dispatch via &dyn Trait produces a ‘wide pointer’ that is twice the size of an ordinary pointer (16 bytes vs 8 on 64-bit): one half points to the data, the other to a vtable that resolves which method to call at runtime. Using an unsafe transmute to peek at the raw pointers, the author shows that all instances of a given type share a single vtable while each instance carries its own data pointer. It’s a practical, memory-first walkthrough for engineers who need to see what’s actually happening under the hood before they trust the abstraction.

Read the full article

Continue reading at Hacker News →

This is an AI-generated summary. Read the original for the full story.