使用局部变量的引用来初始化 constexpr 变量是否有效?

问题描述 投票:0回答:1

以下代码只能在 GCC 上编译(在 godbolt.org 上检查了 10.4 和 13.2),但不能在 Clang 上编译(在我尝试过的所有版本上都失败,例如 godbolt.org 上的 17.1):

struct A {
  static constexpr int b{1};
};

int main(int argc, char *argv[]) { 
    A a;
    A& aref{a};
    constexpr auto bb1{a.b};
    constexpr auto bb2{aref.b};
    return bb1+bb2; 
}

Clang 输出:

<source>:9:20: error: constexpr variable 'bb2' must be initialized by a constant expression
    9 |     constexpr auto bb2{aref.b};
      |                    ^  ~~~~~~~~
<source>:9:24: note: initializer of 'aref' is not a constant expression
    9 |     constexpr auto bb2{aref.b};
      |                        ^
<source>:7:14: note: declared here
    7 |     A& aref{a};
      |   

https://godbolt.org/z/nG4j3KefE

为什么?

c++ clang language-lawyer constexpr
1个回答
0
投票

这是一个很好的问题,我觉得这个问题和这个有类似的“物种”。最后一个答案(对这个问题)有一条评论,指出 gcc 无法识别错误,这是贯穿上述答案的主题。 你的问题的答案可能只是一个平淡无奇的“clang 比 gcc 更紧密地遵循 C++ 标准”。我相信每个人都知道编写编译器绝非易事,有些语法只是逃避了标记器/开发团队等。再加上完成软件的下行压力,GCC 团队无法涵盖所有内容当前 C++ 标准以及 LLVM 团队的各个方面。

引用这篇文章(接近结尾):“Clang和LLVM比GCC更严格地遵守C和C++标准。GCC升级过程中不会出现GNU Inline等问题。”

这是一个不那么平淡的答案

如果

A a;
是全局的,即在 

main() 之前声明,clang 版本也会编译,因为任何引用都不会是本地对象,因此可能是 const (对于 constexpr)。对本地对象的引用(即使在 main() 中也不被视为 const)

© www.soinside.com 2019 - 2024. All rights reserved.