C++ for Systems Programmers

constexpr, consteval and constinit

Some computations never need to happen while your program is running because their inputs are already known when you compile — a lookup table, the size of a buffer, a hashed string literal. If you can push that work into the compiler, the running program just reads a precomputed answer, paying nothing at run time. These three keywords are C++'s controls for shifting computation and initialization from run time to compile time.

constexpr means 'this can be evaluated at compile time if its inputs are constant'. A constexpr function may run during compilation when called with compile-time-known arguments (producing a constant baked into the binary) but may also run normally at run time if called with runtime values — it is permission, not a command. consteval is stronger: it marks an immediate function that must be evaluated at compile time, every call, with no runtime fallback at all; if you cannot evaluate it at compile time, the program does not compile. constinit is the odd one out — it is not about computing a value but about when a variable is initialized: it requires that a static or global variable be given its value during compile-time/constant initialization, ruling out the notorious 'static initialization order fiasco' and any hidden run-time startup work, though the variable may still be mutated later (it is not const).

Why it matters: compile-time evaluation is a clean expression of the zero-overhead principle — you trade a slower build for a faster, smaller, more predictable run. It is heavily used for tables, validation, and metaprogramming, and modern C++ lets remarkably rich code (loops, allocations, even some containers) run at compile time. The honest limits: not everything is allowed in a constant-evaluation context (no undefined behavior, no calling non-constexpr functions, restrictions on what may be allocated), a constexpr function is not guaranteed to run at compile time unless the context forces it, and constinit constrains initialization timing only — it does not make the variable immutable.

constexpr int sq(int n) { return n * n; } constexpr int k = sq(8); // 64 computed at compile time; char buf[k]; is then a fixed-size array

Because sq(8) has a constant argument and constexpr permits it, the value 64 is baked into the binary — zero run-time work.

constexpr is permission to evaluate at compile time, not a guarantee: call a constexpr function with a runtime value and it runs at run time like any other. Use consteval when you must forbid the runtime path, and remember constinit fixes initialization timing only, not mutability.

Also called
compile-time evaluationconstant expressions編譯期求值常數運算式