I found myself in a weird spot, with the error message "expression did not evaluate to a constant":
constexpr uint64 createDynamicPipelineStateMask();
static inline constexpr uint64 dynamic_state_mask = createDynamicPipelineStateMask();
struct CullMode
{
static constexpr inline bool bIsDynamicState = false;
static constexpr inline uint64 mask = 0;
};
constexpr uint64 createDynamicPipelineStateMask()
{
uint64 dynamic_mask = 0;
if constexpr (CullMode::bIsDynamicState) dynamic_mask |= CullMode::mask;
return dynamic_mask;
}
Now I guess I could just move the constexpr value to below the definition, but I wanted to know the answer to this question. I know that it's compiler, and not the linker that needs the full definition of the constexpr function, but the compiler has it right below.
I know that it's compiler, and not the linker that needs the full definition of the constexpr function, but the compiler has it right below .
The behavior of the program can be understood using expr.const#5 which states:
5. An expression E is a core constant expression unless the evaluation of E, following the rules of the abstract machine ([intro.execution]), would evaluate one of the following:
5.2 an invocation of an undefined constexpr function ;
(emphasis mine)
This means that when writing
//------------vvvvvvvvv--------------------------> note the constexpr here, this is not allowed because the call expression cannot be used in a constexpr context until the function is defined
static inline constexpr int dynamic_state_mask = createDynamicPipelineStateMask();
the call expression createDynamicPipelineStateMask()
at this point is an invocation of an undefined constexpr function and so the initializer is not a constant expression according to the above quoted statement which in turn means that it cannot be used as an initializer to initialize dynamic_state_mask
. Basically, you can't use the call expression createDynamicPipelineStateMask()
in a constexpr context until the function is defined.
But the following is perfectly fine.
//------------v-------------------------->note no constexpr here, this is allowed
static inline int dynamic_state_mask = createDynamicPipelineStateMask();
This time, even though createDynamicPipelineStateMask()
does not evaulate to a constant expression, it can still be used as an initializer to initialize dynamic_state_mask
as we have removed the constexpr
specifier from the left hand side of the declaration. Basically this isn't a constexpr context and so using the call expression as an initializer is fine.
Perhaps a contrived example might clear this further:
constexpr int func();
//constexpr int i = func(); //not allowed as the call expression func() at this point is an invocation of an undefined constexpr function and so the initializer is not a constant expression
int i = func(); //allowed
constexpr int func()
{
return 4;
}
constexpr int j = func(); //allowed
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.