In C++20, we have the consteval
keyword that declares an immediate function. For example:
consteval int f(int x) { return x * x; }
Such a function is required to produce a constant expression. However, according to the standard, a constant expression is not required to be actually evaluated at compilation time, unless it is used in a place where a constant is required, such as in a template parameter. For example, nothing in the standard seems to require that this is evaluated at compilation time:
int a = f(10);
However, the requirements strongly suggest that an immediate function is meant to be evaluated at compilation time.
It also appears that nothing in the standard requires that a constexpr variable be evaluated at compilation time. So even if we make the variable constexpr
, i.e.
constexpr int a = f(10);
it only asserts that f(10)
is a constant expression and makes a
a constant expression (but again nothing about constant expressions require that they are actually evaluated at compilation time). However, just like before, the requirements for constexpr variables strongly suggest that they are meant to be evaluated at compilation time.
Only constinit variables are defined differently - constinit variables are required to have static initialization, so they must be calculated at compilation time and embedded directly in the binary. However, this answer to a related question says that constexpr implies constinit, at least for global variables, which seems to contradict what I've written above.
So, are consteval functions and constexpr variables guaranteed to be evaluated at compilation time?
Side note: My actual use case involves trying to initialize a field in a struct with a constant, like this:
consteval int my_complicated_calculation() {
// do complicated mathematics and return an int
}
struct A {
int value;
A() : value{my_complicated_calculation()} {}
}