The Limits of Devirtualization

I’ve seen discussions in the past[1] (I may even have been part of them) where it’s been asked why a vtable interface is necessary for things like allocators, and I think the same question is relevant for IO. These are things which aren’t normally switched at run-time, so why doesn’t a static duck-typing approach work.

I think you can classify the responses into a few different classes. The VTable approach…

  • …avoids needing to have function parameters of type type everywhere in code.
  • …makes the compiler’s job easier as otherwise all types including references need to be generic.
  • …avoids the compiler instancing multiple versions of multiple large specialised versions.
  • …has a low runtime overhead, if any once optimisations have taken place.

However, if you’ve got to carry the overhead of compiling and including a whole sub-section of the standard library just to use a couple of functions then maybe that’s not always the way you’d choose. Sometimes maybe you just want to compile the few functions you use and nothing more. My ideal would be that the std-lib would allow for both styles. Vtables when it’s better. Static ducks when that’s better.

I’d like a way to give a name to “any type with these decls”. [2] I think that is probably orthogonal to what type of implementation is behind it though. You can have straight functions or VTable trampolines.

…or maybe you’re thinking the VTable itself needs a special type / annotation to allow it to be optimised down to whatever is used?


  1. ↩︎

  2. However, I also see it’s easy to get dragged down the full “type classes” road once you have that. That’s a really powerful paradigm, but not necessarily what Zig needs. ↩︎

4 Likes