c++98/03 标准中不存在 std::atomic,无法使用;必须降级为编译器内置(如 __sync_fetch_and_add)或平台 api(如 windows interlockedexchange),且 boost.atomic 是更安全的兼容方案。

用 std::atomic 但不依赖 C++11?不行,得降级处理
直接说结论:C++98/03 标准里没有 std::atomic,强行封装只能靠编译器内置(如 __sync_fetch_and_add)或平台 API(Windows 的 InterlockedExchange),标准库层面无解。如果你的项目必须兼容 GCC 4.1 或 MSVC 2005 之前的环境,std::atomic 就不能用——不是写法问题,是根本不存在。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 先确认最低支持标准:若能接受 C++11,优先用
std::atomic,它本身已跨平台且由标准保证语义 - 若真卡在旧标准,别自己手写内存栅栏+汇编,风险远高于收益;改用成熟轻量封装,比如 Boost.Atomic(它对旧编译器做了 fallback)
- 注意:GCC 4.4+ 支持
__atomic系列内置函数(比__sync更规范),但 MSVC 2005 只认Interlocked*,二者无法统一宏定义隐藏
std::atomic 在不同编译器上行为不一致?看对齐和大小
即使都用 C++11,std::atomic<t></t> 是否 lock-free,取决于 T 类型是否满足平台原生原子指令要求。常见坑是:在 x86 上 std::atomic<int64_t></int64_t> 是 lock-free,但在某些 ARMv7 编译器(如早期 Android NDK)上却 fallback 到 mutex,性能断崖下跌。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 永远检查
std::atomic<t>::is_lock_free()</t>,尤其在嵌入式或移动平台构建后运行时验证 - 避免对自定义结构体直接套
std::atomic:哪怕只有两个int,也可能因 padding 或对齐导致非 lock-free - GCC/Clang 下可用
__attribute__((aligned(16)))强制对齐,但 MSVC 要用__declspec(align(16)),二者不可混用 - 示例:
static_assert(std::atomic<uint64_t>::is_lock_free(), "64-bit atomic not lock-free on this platform");</uint64_t>
旧代码里用 volatile 模拟原子操作?危险,立刻停用
volatile 只禁用编译器优化,不提供线程间可见性保证,也不阻止 CPU 乱序执行。你在 GCC 4.8 上看似“正常”的 volatile int counter; 自增,在 ARM 或带弱内存模型的 CPU 上大概率出错。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 把所有用
volatile做同步的地方标记为 TODO,替换路径分三档:
– C++11+ →std::atomic
– C++03 + GCC →__atomic_fetch_add
– C++03 + MSVC →InterlockedIncrement - 注意 Windows 的
LONG是 32 位有符号,而std::atomic<int32_t></int32_t>是无符号,类型不匹配会导致符号扩展隐患 - 不要用
#ifdef _WIN32直接切分支,容易漏掉交叉编译场景(比如用 MinGW 编译 Windows 程序,它走的是 GCC 内置函数路径)
封装层要不要加 memory_order 参数?要看调用方是否真需要
多数业务逻辑其实只需要 memory_order_seq_cst(默认),强行暴露 memory_order_relaxed 等参数,反而让使用者踩内存序陷阱。但高性能模块(如无锁队列)必须精确控制。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 对外接口默认不暴露
memory_order,内部统一用seq_cst;只在明确标注 “high-performance” 的头文件里提供带序参数的重载 - 如果封装了
fetch_add,注意 GCC/Clang 的__atomic_fetch_add要求第三个参数是__ATOMIC_*宏,而 MSVC 的InterlockedExchangeAdd固定为 full barrier,没法降级 - 测试时用 ThreadSanitizer(Clang/GCC)或 /RTCc(MSVC)捕获非法重排序,比人工 review 可靠得多
跨平台原子封装最麻烦的从来不是语法,而是不同平台对“原子”二字的物理实现差异:x86 默认强序,ARM 需显式 dmb,RISC-V 还要区分 A/C 扩展。别指望一层宏搞定,该分文件就分文件,该 runtime 检测就检测。










