cppreference said the following about the body of a constexpr function:
the function body must not contain:
- a definition of a variable of non-literal type
- a definition of a variable of static or thread storage duration.
All I understood about a constexpr function is that the statements in its body should be evaluated at compile-time so that the call expression can be evaluated at compile-time. Am I true?
Since C++14, the standard allows the body to contain variable definitions of literal types. So what about those definitions, are they evaluated at compile-time or runtime? since non-constexpr variables are allowed also.
What I think I misunderstood is that the compiler shall be able to evaluate at compile-time every statement in a constexpr function body. Does this true since C++14?
To make my confusion clear, I have this simple example:
// assuming std::is_literal_type<T> is true.
constexpr T f() { T t{}; return t; };
I can't understand how the compile behaves with the above snippet. Variable t
is an automatic non-const variable and gets defined at run-time not compile-time; so it basically cannot appear in a constexpr declaration. Does this means, the compiler will never evaluate f()
at compile-time because it has a statement, that's T t;
, which will be evaluated at runtime only.
My confusion is increased when I have tried:
constexpr T result = f();
and it compiles successfully!. Does this mean f()
are evaluated at compile-time? if yes, what about the runtime definition of t
?
My second question is about why static-duration variables are not allowed in the body of a constexpr function.
...along at least one possible code path.
Or, as the cpprefenrce page you're quoting puts it,
The function can be doing disk I/O if it wants to, as long as there is an if branch that skips it.
It's defined in both. There is a run-time definition of the function (actual machine code compiled and written to the object file) and also there is a compile-time version of the function, a bunch of AST nodes or some sort of internal compiler representation of them. In a constexpr context, compile-time version will be evaluated and replaced by its result. In runtime context, a function call instruction will be compiled.