wimalopaan wimalopaan - 13 days ago 6
C++ Question

Nesting contexpr functions error

The follwing code doesn't compile with g++/clang++.

constexpr int bar(int v) {
if (v > 0){
return v * 2;
}
return 2;
}

constexpr int foo(const int v) {
constexpr auto x = bar(v); // error
return v;
}

int main() {
constexpr auto a = foo(1);
constexpr auto b = bar(1); // ok
}


The error message is: x must be initailized by a constant expression

But from the line (ok) you see that bar() is constexpr.

if I change the body of foo() to

constexpr int foo(const int v) {
return bar(v);
}


its ok!

I don't get this clear, why the first form isn't possilble.
I used g++-6.2.1, g++-7.0.0 and clang++-3.9.0

Tim Tim
Answer

The fix is this

constexpr int foo(const int v) {
    auto x =  bar(v);
    return v;
}

The keyword constexpr means two very slightly different things. A constexpr variable must be evaluated at compile time, whereas a constexpr function must be possible to evaluate at compile time. There is nothing to prevent you from calling foo at runtime. This means...

  1. The argument v is not necessarily constexpr.
  2. When bar is called with b the answer might not be constexpr.
  3. The result of cannot be stored in a constexpr variable as it might not be constexpr.

If foo is called at compile time then x is not stored, it is a temporary variable within the compiler, so making it constexpr doesn't make any sense.

The constexpr'ness of x can only make sense if foo is evaluated at runtime, in which case it cannot be constexpr, which cases an error.

Comments