c++ 遇到错误:使用clang-cl编译时,默认构造函数的默认定义不是constexpr

vd2z7a6w  于 2022-12-20  发布在  其他
关注(0)|答案(1)|浏览(281)

我正在尝试使用clang-cl和LLVM 15编译这些代码。

class Foo
{
public:
    constexpr Foo() = default;
private:
    int i;
};

int main(void)
{
    Foo f;
}

编译命令行为:

\> bazel build ... --compiler=clang-cl

将显示错误

cpp-constexpr/main.cpp(4,5): error: defaulted definition of default constructor is not constexpr
    constexpr Foo() = default;
    ^
cpp-constexpr/main.cpp(13,9): error: no matching constructor for initialization of 'Foo'
    Foo f;
        ^
cpp-constexpr/main.cpp(6,5): note: candidate constructor not viable: requires 1 argument, but 0 were provided
    Foo(const Foo&) = delete;
    ^
2 errors generated.
Target //cpp-constexpr:constexpr failed to build

如果是用MSVC 2022/2019编译的,根本不会有任何错误。期待已知你的建议。
先谢了。

enxuqcxy

enxuqcxy1#

TL; DR版本:编译为C20或更新版本的C标准,两个编译器都应该接受此代码。你可能会发现他们对C20的处理有其他的差异,而且情况也没有好转。
说明:
引用cppreference
对于类或结构的构造器,必须初始化每个基类子对象和每个不变的非静态数据成员。
这在C
20之前是有效的。从C++20开始,代码应该按照所提供的工作(但是如果我知道你将如何处理一个常量未初始化的变量i,那就危险了。必须深入研究标准或深入研究cppreference,看看i是否是零初始化的或什么的。This experiment with Matt Godbolt's compiler Explorer建议它没有初始化。
因此,修复程序最有可能初始化i

class Foo
{
public:
    constexpr Foo() = default;
    ~Foo() = default;
    Foo(const Foo&) = delete;
private:
    int i = 0;
};

MSVC在C20之前编译这段代码的能力似乎是一个可以在任何时候修复的bug。与其强迫clang-cl执行不正确的行为,我建议修复代码(或者将两端都编译到C20或更高版本)。

相关问题