Runtime polymorphism uses an abstract base class with virtual methods; the app holds an IGpio&/IGpio* and calls dispatch through a vtable to the actual object's method at run time. It costs a vtable pointer per object and a non-inlinable indirect call, but lets you choose or swap the implementation at runtime and hold heterogeneous collections (an array of different IGpio*). Compile-time polymorphism templates the app logic on the driver type (Blinker<Stm32Gpio>); calls bind at compile time, so they're direct and inlinable, zero runtime overhead, but the type is fixed at build time and each instantiation generates separate code. Rule of thumb: use the template approach for hot paths and when the driver is known at compile time (most firmware), and use virtuals when you genuinely need runtime selection, heterogeneous collections, or a stable cross-module binary interface. Both give portability and testability; they differ only in when binding happens and what it costs.
C++ for Embedded · Interview question
What's the difference between runtime and compile-time polymorphism for a HAL, and when do you use each?
A strong answer
What a weak answer sounds like
You know the answer. Do you know what gets you dinged?
Pro breaks down the answer most candidates actually give to this question — and the specific reason an interviewer marks it down. It’s the difference between sounding correct and sounding senior, on all 472 questions.
From the lesson
The HAL Pattern
Abstract a peripheral behind an interface so app logic survives an MCU swap and runs in a PC unit test, using runtime virtuals or zero-overhead compile-time polymorphism.