std::is_constant_evaluated behavior

  • A+
Category:Languages

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.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: