You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LLVM 15 clang-cl编译constexpr默认构造函数代码报错求助

解决clang-cl 15编译constexpr默认构造函数报错的问题

我尝试用LLVM 15版本的clang-cl编译以下代码:

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编译该代码时完全没有错误,希望能得到解决建议。


问题原因

根据C标准(C11及后续版本),被constexpr修饰的默认构造函数若为= default,要求所有非静态数据成员都能被常量初始化。你的Foo类中int i未指定初始化值,不符合constexpr构造函数的标准约束——clang-cl严格遵循了这一规则,而MSVC对该标准做了非标准的放宽处理,因此两者编译结果存在差异。

解决办法

可根据实际需求选择以下方案:

  • 给成员变量添加常量初始化值
    如果确实需要constexpr构造函数,给i指定编译期常量初始值,满足标准对constexpr的要求:

    class Foo
    {
    public:
        constexpr Foo() = default;
    private:
        int i = 0; // 添加常量初始化值
    };
    
  • 移除constexpr修饰符
    若不需要在编译期构造Foo对象,直接去掉constexpr,让构造函数回归普通默认构造:

    class Foo
    {
    public:
        Foo() = default; // 移除constexpr
    private:
        int i;
    };
    
  • 调整clang-cl编译选项兼容MSVC行为
    如果需要保持代码与MSVC一致的行为,可给clang-cl添加-frelaxed-constexpr选项,放宽对constexpr构造函数的检查(注意此选项会偏离标准,仅适用于兼容旧代码或特定场景)。在bazel中可通过编译命令传递该选项:

    > bazel build ... --compiler=clang-cl --copt=-frelaxed-constexpr
    

内容的提问来源于stack exchange,提问作者Erxin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 10:30:53