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

为何该C++程序在macOS可编译但Ubuntu不行?Clang版本均为10

这不是未定义行为,本质是两个系统使用了不同的C标准库实现带来的差异:Ubuntu上的Clang搭配的是GCC的**libstdc,而macOS上的Clang用的是LLVM的libc++**,两者对std::atomic<T>的实现细节有区别。

为什么Ubuntu编译失败?

根据C14标准,std::atomic<T>只要求T是**可平凡复制(trivially copyable)**的类型,但你Ubuntu上用的旧版本libstdc(搭配的是GCC 5.4.0)在实现atomic::load()时,会尝试默认构造一个T类型的临时对象(错误信息里的_Tp tmp;就是这个操作),这就要求T必须有可访问的默认构造函数。而你的foo类只定义了带两个参数的构造函数,编译器不会自动生成默认构造函数,所以触发了编译错误。

反观macOS的libc++,它的atomic::load()实现没有依赖默认构造函数,而是直接通过内存操作读取值,不需要临时对象的默认构造,所以你的代码能正常编译。

如何让两个环境编译结果一致?

有几种可行的方案:

  • 给foo添加默认构造函数:这是最直接且兼容性最好的方法,比如:

    struct foo {
        bool bar;
        int baz;
        foo() = default; // 显式声明默认构造函数
        foo(bool bar, int baz) : bar(bar), baz(baz) { }
    };
    

    这样既满足libstdc的要求,也不会影响libc的编译。

  • 升级Ubuntu上的libstdc++版本:较新的libstdc++已经修正了这个问题,不再要求T必须有默认构造函数(只要满足可平凡复制即可)。如果你的Ubuntu系统允许,可以升级到更高版本的GCC标准库。

  • 在Ubuntu上强制使用libc++编译:如果你想和macOS保持一致的标准库,可以让Clang使用libc++编译,命令如下:

    clang++ -std=c++14 -stdlib=libc++ test.cpp -o test
    

    注意:Ubuntu默认可能没有安装libc++,需要先执行sudo apt install libc++-dev libc++abi-dev完成安装。

补充说明

你提到从std::atomic的文档里找不到默认构造函数的要求,这完全正确——C标准确实没有这个要求,这只是旧版libstdc的实现细节。macOS的libc++实现更贴合标准的规定,所以没有这个额外限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:23:14