user2023370
user2023370

Reputation: 11054

Non-literal within a constexpr function (via std::is_constant_evaluated)

In a constexpr function, I am unable to define a non-literal variable within the branch of an if statement conditioned by C++20's std::is_constant_evaluated()? Clang and GCC both indicate it is not permitted, but in the example below, other constructs which cannot be evaluated at compile-time are permitted. Is there a specific restriction on the use of non-literals?

#include <type_traits>

struct Foo {
  ~Foo() {}
};

void non_constexpr() {}

constexpr bool bar()
{
  if (std::is_constant_evaluated()) {
  } else {
    non_constexpr();
    double d;
    reinterpret_cast<int*>(&d);
    Foo f;  // error: variable ‘f’ of non-literal type ‘Foo’ in ‘constexpr’ function
  }

  return true;
}

constexpr bool x = bar();

Upvotes: 3

Views: 525

Answers (1)

There is a specific restriction. In this case a structural restriction about the bodies of constexpr functions.

[dcl.constexpr]

3 The definition of a constexpr function shall satisfy the following requirements:

  • its function-body shall not enclose
    • a definition of a variable of non-literal type or of static or thread storage duration.

That's the long and short of it. If you are left wondering why it is so, given no forbidden code will be executed in constant evaluation, that's a good question too. Unfortunately I'm not aware of the answer to that at the moment. It might just be something no one has yet thought to change.

Upvotes: 3

Related Questions