【问题标题】:Is the initializer of a constexpr variable at class scope allowed to reference the variable?类范围内的 constexpr 变量的初始化程序是否允许引用该变量?
【发布时间】:2021-10-19 01:30:41
【问题描述】:

以下代码:

struct S {
    static constexpr int rolling_sum[4]{
        0,
        rolling_sum[0] + 1,
        rolling_sum[1] + 2,
        rolling_sum[2] + 3
    };
};

被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
      |         ^~~~~~~~~~~

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

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

【问题讨论】:

  • 它似乎在类似的测试中工作:godbolt.org/z/sYY84zehh(但在实际示例中仍然没有,不知道为什么)。似乎问题可能与struct 中定义的数组有关。

标签: c++ c++14 language-lawyer constexpr


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    正如您引用的 [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
        };
    };
    

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

    【讨论】:

      【解决方案3】:

      代码被clang 接受。如果数组在namespace scope 声明,它也被gcc 接受,这让我相信:

      在类范围内拒绝它可能是一个错误

      ICC 和 MSVC 甚至类似于GCC 拒绝它。

      我相信它是有效的,因为变量的 point of declaration 就在其初始化之前,因此该变量应该在其初始化程序的范围内。 Point of declaration

      但我不是措辞专家,有可能我弄错了,或者忽略了其他会使此内容无效的内容。

      Bug 99059 类似。

      【讨论】:

        猜你喜欢
        • 2019-12-14
        • 2012-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-13
        • 1970-01-01
        相关资源
        最近更新 更多