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

std::atomic的平凡默认构造函数是否应遵循默认成员初始化器?

关于std::atomic<stru>成员初始化的问题分析

咱们先把问题里的代码贴出来方便讨论:

#include <atomic>
#include <iostream>
struct stru { int a{}; int b{}; };
int main() { std::atomic<stru> as; auto s = as.load(); std::cout << s.a << ' ' << s.b << std::endl; }

先明确几个关键前提

  • 你说的没错,C++14及以后,带默认成员初始化器的结构体stru依然属于聚合类型。
  • std::atomic<stru>的默认构造函数是平凡默认构造函数——简单说就是这个构造函数啥也不做,不会主动初始化内部的stru实例。

标准到底怎么规定的?

根据C++标准的规则:

  • 对于静态存储期的对象(比如定义在main函数外面的全局变量),会先执行零初始化,再调用默认构造函数。因为std::atomic的默认构造是平凡的,啥也不做,所以最终as内部的stru成员会被零初始化,a和b都是0。
  • 但对于自动存储期的对象(比如代码里main里的as),平凡默认构造函数不会执行任何初始化操作——对象的内存就是未初始化的垃圾值,自然load()出来的a和b也不会是0。

这里要注意:stru的默认成员初始化器只有在聚合初始化的时候才会生效,而平凡默认构造函数不会触发聚合初始化。也就是说,std::atomic<stru> as;这种写法,不会调用stru的任何初始化逻辑,只是分配了一块内存而已。

为什么Clang 6.0.0没初始化?

Clang 6.0.0的行为是完全符合标准的。因为代码里的as是自动存储期的变量,用平凡默认构造创建,内存未初始化,所以输出的是随机垃圾值。

怎么让成员初始化为0?

如果想让a和b变成0,有两种方式:

  • 把as改成静态存储期,比如移到main外面定义:std::atomic<stru> as;(全局变量)。
  • 用聚合初始化的方式显式初始化as:std::atomic<stru> as{};——这会触发内部stru的聚合初始化,从而让默认成员初始化器生效,把a和b设为0。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:03:20