Q&A
What is the constexpr keyword in C++?
Overview
constexpr tells the compiler "this can be computed at compile time." Doing work at compile time means zero runtime cost for those computations and lets results be used where the language requires a constant expression. It's stronger and more flexible than the old const, and the modern C++ standards have expanded what constexpr functions can do.
graph TD
A[constexpr] --> B[Variable: compile-time constant]
A --> C[Function: MAY evaluate at compile time]
C --> D{Called with constant args?}
D -->|yes| E[Computed at compile time, zero runtime cost]
D -->|no| F[Runs normally at runtime]
style E fill:#1e1b4b,color:#fff
constexpr Variables
A constexpr variable must be initialized with a constant expression and is fixed at compile time:
constexpr int SIZE = 100;
constexpr double PI = 3.14159;
int arr[SIZE]; // OK: SIZE is a compile-time constant
const vs constexpr
They're related but distinct:
const int a = getValue(); // const: can be set at RUNTIME, just not reassigned
constexpr int b = 42; // constexpr: MUST be known at COMPILE time
// constexpr int c = getValue(); // ❌ error if getValue() isn't constexpr
const- "won't change after initialization" (may be a runtime value).constexpr- "known at compile time" (a stronger guarantee). Everyconstexpris effectivelyconst, but not vice versa.
constexpr Functions
A constexpr function can be evaluated at compile time when its arguments are constant expressions:
constexpr int factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
constexpr int f5 = factorial(5); // computed at COMPILE time → 120
int x = 6;
int fx = factorial(x); // computed at RUNTIME (x isn't constant)
The same function serves both: compile-time when possible, runtime otherwise. This dual nature is the key idea.
Use in Compile-Time Contexts
constexpr values can go where constant expressions are mandatory:
constexpr int N = factorial(4); // 24
std::array<int, N> data; // array size must be a constant expression
template <int X> struct Tag {};
Tag<factorial(3)> t; // template argument must be constant
Evolution Across Standards
- C++11 -
constexprfunctions limited to (essentially) a single return statement. - C++14 - loops, multiple statements, local variables allowed in
constexprfunctions. - C++17 -
if constexpr(compile-time branching in templates),constexprlambdas. - C++20 -
consteval(functions that must run at compile time),constinit, much more (even someconstexprdynamic allocation/std::vector/std::string).
// C++17 if constexpr - compile-time branch selection
template <typename T>
auto process(T value) {
if constexpr (std::is_integral_v<T>) return value * 2;
else return value + " processed";
}
constexpr vs consteval (C++20)
constexpr- may run at compile time (or runtime if needed).consteval- must run at compile time (an "immediate function"); calling it with runtime values is an error.
Benefits
- Performance - results precomputed during compilation; no runtime cost.
- Enables constant-expression contexts - array sizes, template args,
enumvalues,static_assert. - Earlier error detection - invalid computations fail at compile time.
- Safer than macros - type-checked, scoped alternatives to
#defineconstants.
Why This Matters in Interviews
C++ interviews use constexpr to test modern-C++ knowledge. Core points: it means compile-time evaluation; the const vs constexpr distinction (runtime-immutable vs compile-time-known); that constexpr functions run at compile time only when given constant arguments (else at runtime); and its use where constant expressions are required (array sizes, templates). Mentioning the standard-by-standard expansion, if constexpr (C++17), and consteval (C++20) demonstrates current expertise.
Common Pitfalls
- Assuming a
constexprfunction always runs at compile time (only with constant args). - Confusing
const(immutable, possibly runtime) withconstexpr(compile-time). - Using non-
constexproperations inside aconstexprfunction (compile error). - Expecting C++11
constexprfunctions to allow loops (that came in C++14). - Reaching for macros where
constexpris the safer, typed choice.
References
- cppreference
constexpr: https://en.cppreference.com/w/cpp/language/constexpr - cppreference
consteval: https://en.cppreference.com/w/cpp/language/consteval