Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a constexpr method through a reference - is the result a constant expression?

The following code

#include <array>

void foo(const std::array<int, 42> &a)
{
  constexpr size_t S = a.size();
}

int main() {}

compiles fine in GCC, but fails to compile in clang with the following error message

main.cpp:5:28: error: constexpr variable 'S' must be initialized by a constant expression
      constexpr size_t S = a.size();
                           ^~~~~~~~

Meanwhile, many posts about constexpr issues on SO seem to imply that clang often has better (more pedantic?) support for constexpr. So, which compiler would be correct in this case?

Note that both compilers gladly accept the code once the reference parameter is replaced with pass-by-value parameter.

like image 651
AnT Avatar asked May 17 '16 23:05

AnT


1 Answers

[expr.const]/2:

A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine ([intro.execution]), would evaluate one of the following expressions:

  • [...]
  • an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either

    • it is initialized with a constant expression or
    • its lifetime began within the evaluation of e;
  • [...]

Evaluating a.size() evaluates the id-expression a, which "refers to a variable...of reference type" and has no preceding initialization. It is therefore not a core constant expression and so not a constant expression.

like image 105
T.C. Avatar answered Sep 18 '22 23:09

T.C.