C++ for Systems Programmers

the zero-overhead principle

There is a fear that high-level conveniences must cost performance — that classes, templates, and smart pointers buy readability at the price of speed. C++ is built around a promise that pushes back on this, usually summarized in two parts by Bjarne Stroustrup: first, you don't pay for what you don't use; second, what you do use, you could not reasonably hand-code any better. This is the zero-overhead principle, and it explains why C++ aims to give you abstraction without an abstraction tax.

Concretely, 'don't pay for what you don't use' means a feature you never invoke imposes no cost on your program — if you don't throw exceptions, the happy path runs at full speed; if you don't use virtual functions, there is no vtable pointer or indirect call. And 'what you use is as efficient as hand-coding' means the abstractions are designed to compile down to the same machine code an expert would write by hand: a std::unique_ptr is the size of a raw pointer and its dereference is a plain load; a range-based for over a std::vector compiles to the same pointer-bumping loop as a hand-written index; a template max<int> is identical to a hand-written integer max. The compiler's job — inlining, monomorphization, optimization — is to make the abstraction evaporate.

Why it matters: this principle is why systems and game and embedded programmers can use modern C++ instead of dropping to C — they get RAII, type safety, and generics while keeping C-level control over memory and time. The honest caveats are real, though: zero-overhead is an aspiration the language is designed toward, not a guarantee in every case. Some features do carry inherent cost (shared_ptr's atomic counts, runtime exceptions on the throw path, virtual dispatch), abstractions are only zero-cost after the optimizer runs (a debug, unoptimized build can be far slower), and 'zero overhead versus equivalent hand-written code' does not mean 'free' — it means 'no worse than doing the same thing yourself'.

for (int x : v) sum += x; // a range-based for over std::vector<int> compiles to the same loop as a raw index walk over v's buffer

The high-level construct optimizes down to the same machine code you would write by hand — abstraction with no run-time tax.

Zero-overhead is measured against equivalent hand-written code, not against nothing: a feature that does real work (atomic refcounts, an actual thrown exception, a virtual call) still costs what that work costs. The promise is 'no worse than doing it yourself', not 'magically free'.

Also called
don't pay for what you don't usezero-cost abstraction零成本抽象不為不用之物付費