通过引用调用constexpr方法 - 结果是一个常量表达式吗?

AnT*_*AnT 7 c++ gcc clang language-lawyer constexpr

以下代码

#include <array>

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

int main() {}
Run Code Online (Sandbox Code Playgroud)

在GCC中编译正常,但无法在clang中编译以下错误消息

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

与此同时,很多constexpr关于SO问题的帖子似乎暗示铿锵经常有更好(更迂腐?)的支持constexpr.那么,在这种情况下哪个编译器是正确的?

请注意,一旦参考参数被pass-by-value参数替换,两个编译器都乐于接受代码.

T.C*_*.C. 7

[expr.const]/2:

条件表达式 e是一个核心常量表达式除非的评价e,如下所述抽象机的规则([intro.execution]),将评估下列表达式之一:

  • [...]
  • 一个id-expression,引用引用类型的变量或数据成员,除非引用具有先前的初始化和任何一个

    • 它是用常量表达式初始化的
    • 它的生命始于评估范围内e;
  • [...]

评估a.size()计算id-expression a,它"引用引用类型的变量"并且没有先前的初始化.因此,它不是核心常量表达式,因此不是常量表达式.