Background
BasicIO<IOTmpl> uses CRTP (Curiously Recurring Template Pattern) for static polymorphism. All *Impl methods are dispatched via static_cast<IOTmpl&>(*this) — there is no dynamic dispatch.
However, the destructor is declared as virtual ~BasicIO() = default; in src/io/basic_io.h:59. This is the only virtual function in the entire hierarchy.
Problem
The virtual destructor introduces an unnecessary vtable pointer (vptr, 8 bytes) into every IO object:
- CRTP is designed for zero-overhead static polymorphism — the vptr defeats this promise
- No IO object is ever deleted through a
BasicIO<>* base pointer (there is no public virtual base class)
- The vptr wastes 8 bytes per object and adds an unnecessary indirect jump
Proposed Fix
-
Change virtual ~BasicIO() = default; to a protected non-virtual ~BasicIO() = default;
- Removes the vptr, restoring zero overhead
protected access prevents external code from deleting through a base pointer (compile-time safety)
-
Remove override from all 7 subclass destructors:
MemoryIO, BufferIO, MMapIO, AsyncIO, ReaderIO, MemoryBlockIO, NonContinuousIO
Expected Impact
- -8 bytes per IO object (vptr elimination)
- Eliminates unnecessary virtual dispatch overhead
- Restores the CRTP zero-overhead design intent
Background
BasicIO<IOTmpl>uses CRTP (Curiously Recurring Template Pattern) for static polymorphism. All*Implmethods are dispatched viastatic_cast<IOTmpl&>(*this)— there is no dynamic dispatch.However, the destructor is declared as
virtual ~BasicIO() = default;insrc/io/basic_io.h:59. This is the only virtual function in the entire hierarchy.Problem
The
virtualdestructor introduces an unnecessary vtable pointer (vptr, 8 bytes) into every IO object:BasicIO<>*base pointer (there is no public virtual base class)Proposed Fix
Change
virtual ~BasicIO() = default;to aprotectednon-virtual~BasicIO() = default;protectedaccess prevents external code from deleting through a base pointer (compile-time safety)Remove
overridefrom all 7 subclass destructors:MemoryIO,BufferIO,MMapIO,AsyncIO,ReaderIO,MemoryBlockIO,NonContinuousIOExpected Impact