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
相关产品推荐
相关产品推荐

