GCC9 already implements std::is_constant_evaluated
. I played a little bit with it, and I realized it is somewhat tricky. Here’s my test:
constexpr int Fn1()
{
if constexpr (std::is_constant_evaluated())
return 0;
else
return 1;
}
constexpr int Fn2()
{
if (std::is_constant_evaluated())
return 0;
else
return 1;
}
int main()
{
constexpr int test1 = Fn1(); // Evaluates to 0
int test2 = Fn1(); // Evaluates to 0
int const test3 = Fn1(); // Evaluates to 0
constexpr int test4 = Fn2(); // Evaluates to 0
int test5 = Fn2(); // Evaluates to 1
int const test6 = Fn2(); // Evaluates to 0
}
According to these results, I extracted the following conclusions:
if constexpr (std::is_constant_evaluated())
always evaluates the
true
branch. Therefore, it makes no sense to use this construct.
If the compiler evaluates a variable at compile time,
std::is_constant_evaluated())
is true
, no matter whether that
variable is explicitly annotated constexpr
or not.
Am I right?
if constexpr
requires a constant expression for a condition. So is_constant_evaluated
is of course always going to be true in such a context.
It's meant for a regular if
. The purpose is to not go into a code path that is illegal in a constexpr
function when evaluated in a constant expression. But to let it execute in runtime. It's not there to eliminate those code paths from the function altogether.