Forcing Compile-Time Evaluation
I used to like to think of constexpr as a hint, meaning it hints the compiler to evaluate what you constexpr-ed at compile time.
That’s not true because it depends on context in the sense that constexpr on a variable is a hard requirement: if the initializer cannot be evaluated at compile time, compilation fails.
constexpr int x = 42; // guaranteed compile-time
constexpr int y = some_func(); // compile error if some_func() can't be evaluated at compile time
constexpr on a function is different. It means “this function is permitted to run at compile time”, but it does not force callers to do so. The function can still be called at runtime:
constexpr int square(int n) { return n * n; }
constexpr int a = square(5); // compile-time (constexpr variable forces it)
int b = square(5); // not required to be compile-time, compiler may optimize it
int n = get_input();
int c = square(n); // runtime (n isn't known at compile time)
So now we can ask how do we force compile-time evaluation then? We have a few options:
-
constexprvariable: forces the initializer to be evaluated at compile time.constexpr int result = square(5); -
static_assert: forces its argument to be evaluated at compile time.static_assert(square(5) == 25); -
constevalfunction (C++20): forces every call to be evaluated at compile time.consteval int square(int n) { return n * n; } int a = square(5); // compile-time, even without constexpr on the variable int n = get_input(); int b = square(n); // compile ERROR: consteval requires compile-time evaluation
TLDR: constexpr on a variable = guaranteed. constexpr on a function = permitted. consteval on a function = mandatory.