ELSEIF
Your brief EB
223 stories from 170 feeds 963 clusters Refreshed 4 minutes ago next pull 03:31

LANGUAGES Signal 314 2 feeds carried it

Explaining Rust dyn Trait memory layout via vtable visualization

The post visualizes how Rust's dyn Trait uses vtables for dynamic dispatch, contrasting it with static dispatch and C++ virtual functions.

WHY IT MATTERS

Seeing the vtable structure clarifies the runtime overhead of dyn Trait versus zero-cost static dispatch. It aids engineers deciding when to use dynamic polymorphism in Rust. The visualization also highlights Rust's zero-sized types and their impact on memory layout.

Written by elseif from the cluster below · every claim links back to a source

The three things worth knowing

01

Rust's dyn Trait employs a fat pointer consisting of a data pointer and a vtable pointer, similar to C++ virtual function tables.

02

Static dispatch through generics monomorphizes functions, removing runtime indirection but increasing code size.

03

Rust permits zero-sized types, allowing empty structs to occupy zero bytes, unlike C++ where empty objects have a minimum size of one byte.

THE READ

What the cluster adds up to.

ORIGINAL ANALYSIS

The article begins by setting up a simple shape example with circles and squares to illustrate polymorphism. It shows how a dyn Trait reference is represented in memory as a wide pointer that holds both the object's address and a pointer to its virtual table. The vtable contains function pointers for each method in the trait, enabling dynamic dispatch at runtime. This layout mirrors the approach used by C++ virtual functions, where each object carries a vtable pointer.

In contrast, the post examines static dispatch via Rust's generics, which monomorphizes the draw_shape function for each concrete type. The compiler generates separate draw_shape::<Circle> and draw_shape::<Square> functions, eliminating any runtime indirection. While this yields zero-overhead calls, it can lead to code duplication and larger binaries. The author notes that this trade-off is analogous to the C++ Curiously Recurring Template Pattern, but resolved at compile time.

A side investigation into the size of empty structs reveals Rust's zero-sized types, where std::mem::size_of::<Circle>() returns zero. The author contrasts this with C++'s rule that every object occupies at least one byte to guarantee distinct addresses. This difference influences how wide pointers are laid out, as a zero-sized type contributes no data payload to the fat pointer. The visualization therefore shows a vtable pointer paired with a zero-byte data slot for such types.

Finally, the discussion turns to practical considerations for choosing between dyn Trait and generics. Engineers must weigh the flexibility of runtime polymorphism against the potential binary size increase from monomorphization. The article also reminds readers that only object-safe traits can be used as dyn Trait, limiting which methods can be included. Understanding these memory layout details helps predict performance impacts and informs decisions when interfacing with C++ code that expects traditional vtables.

Written by elseif from the cluster below · checked for specifics the sources never contained

THE CLUSTER

Same story, 2 feeds.

ORDERED BY FIRST SEEN
sofiabelen.github.io via Lobsters Visualizing Rust's Vtables: How dyn Trait Works In Memory Open ↗
sofiabelen.github.io via Hacker News Visualizing Rust's Vtables: How dyn Trait Works In Memory Open ↗