Search code examples
c++constexprc++20if-constexpr

std::is_constant_evaluated behavior for const variables


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?


Solution

  • 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.