ReviseAlgo Logo

Templates

constexpr and Compile-Time Computation

Compute values, execute logic, and construct objects directly at compile time using constexpr and consteval.

Interview: Crucial for high-performance C++ pipelines. Focuses on constexpr vs const, runtime fallback conditions, consteval, and constinit.

Last Updated: June 13, 2026 10 min read

C++ supports Compile-Time Computation, allowing developers to execute functions and construct structures during compilation. This shifts computation overhead from runtime to compile time, saving CPU cycles.

constexpr

Instructs the compiler that the function or variable can be evaluated at compile time if inputs are known then.

consteval

Introduced in C++20. Declares an immediate function that must produce a compile-time constant, or error.

constinit

Enforces compile-time initialization of static variables to prevent the static initialization order fiasco.

constexpr vs. const

While both keywords declare read-only values, their semantics differ:

  • const: Means "read-only" at runtime. The initialization value can be determined at runtime (e.g. reading user input or system time).
  • constexpr: Means "constant expression". The value must be known at compile time. All constexpr variables are implicitly const.

Code Walkthrough

This example demonstrates compile-time calculations using constexpr and consteval functions.

#include <iostream>
#include <array>

// constexpr functions can run at compile-time OR runtime constexpr int factorial(int n) { return (n <= 1) ? 1 : n * factorial(n - 1); }

// consteval functions MUST run at compile-time consteval int square(int n) { return n * n; }

int main() { // Computed at compile-time because the target size requires constant expression std::array<int, factorial(5)> my_arr; std::cout << "Array size: " << my_arr.size() << std::endl; // 120

// Evaluated at runtime since input is dynamic int val = 4; int fact_val = factorial(val); std::cout << "Fact: " << fact_val << std::endl;

// Compile-time evaluation enforced by consteval constexpr int sq = square(10); // int bad_sq = square(val); // COMPILE ERROR: val is not compile-time constant

return 0; }

Interview-Relevant Information

Q: Can constexpr functions contain loops and dynamic allocations?
Answer: Since C++14, constexpr functions can contain loops, conditional statements, and local variable mutations. Since C++20, transient dynamic allocations (using std::vector or new/delete) are permitted inside constexpr, provided the memory is fully deallocated before the compile-time execution finishes.

Q: What is the Static Initialization Order Fiasco and how does constinit help?
Answer: It occurs when global/static variables across different translation units depend on each other's initial value. The initialization order of different source files is undefined, leading to reading uninitialized variables. constinit guarantees the variable is initialized at compile time, eliminating order issues.

Quick Checklist

Do you know when constexpr falls back to runtime? Can you write a consteval function? If yes, you understand compile-time computations.

Use Cases

Building static lookup tables (like trigonometric calculations or hash values) at compile time.

Configuring compile-time fixed buffers or template sizes without runtime performance hits.

Common Mistakes

Assuming a constexpr function ALWAYS runs at compile time (it only runs at compile time if the result is assigned to a constexpr variable or template size requirement). Use consteval to force it.

Using non-literal types (like file streams or network sockets) inside constexpr operations.