类范围内的 constexpr 变量的初始值设定项是否允许引用该变量?

HC4*_*ica 18 c++ language-lawyer constexpr c++14

以下代码:

struct S {
    static constexpr int rolling_sum[4]{
        0,
        rolling_sum[0] + 1,
        rolling_sum[1] + 2,
        rolling_sum[2] + 3
    };
};
Run Code Online (Sandbox Code Playgroud)

被 clang 接受(用版本 12 测试),但被 gcc(用版本 11 测试)拒绝,并出现以下错误:

test.cpp:4:9: error: ‘rolling_sum’ was not declared in this scope
    4 |         rolling_sum[0] + 1,
      |         ^~~~~~~~~~~
test.cpp:5:9: error: ‘rolling_sum’ was not declared in this scope
    5 |         rolling_sum[1] + 2,
      |         ^~~~~~~~~~~
test.cpp:6:9: error: ‘rolling_sum’ was not declared in this scope
    6 |         rolling_sum[2] + 3
      |         ^~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

这段代码是有效的 C++ 吗?

我的猜测是它应该是有效的,因为[basic.scope.pdecl] p1声明变量的声明点就在其初始化程序之前,这意味着该变量应该在其初始化程序的范围内;但我不确定我是否忽略了其他可能与此相关的内容。

Sto*_*ica 6

你没有遗漏任何东西。这是GCC bug 99059,在 GCC 11 中报告。

您的情况也适用,因为就像 一样static inlineconstexpr变量必须在声明时初始化。与查找相关的相同错误也会影响 C++14 代码。


dfr*_*fri 5

正如您引用的[basic.scope.pdecl]/1所允许的那样(因为 /3 和转发都没有拒绝它),您的程序格式良好。

我们可以研究一个类似的例子,GCC 令人困惑地拒绝了以下部分内容:

struct S {
    static constexpr int x{42};
    static constexpr int y[2]{
        S::x,        // #1 GCC: OK
        S::y[0] + 1  // #2 GCC: error: incomplete type 'S' used in nested name specifier
    };
};
Run Code Online (Sandbox Code Playgroud)

在 #2 处有一条错误消息,可以说(如果它不是拒绝无效的话)应该应用于 #1。