能否在MSVC(v143)中使用GCC内置原子内存访问函数?
在MSVC(v143)中使用GCC原子内存访问内置函数的实现方案
由于无法切换到Clang,你可以通过宏封装适配或标准库替代两种方式在MSVC(v143)环境下兼容GCC的原子内置函数,以下是具体实现:
方案1:宏封装MSVC原生原子函数适配GCC接口
MSVC提供了与GCC原子函数对应的原生内置函数和内存序枚举,通过条件编译宏直接映射即可:
#ifdef _MSC_VER // 映射GCC内存序常量到MSVC的memory_order枚举 #define __ATOMIC_RELAXED memory_order_relaxed #define __ATOMIC_CONSUME memory_order_consume #define __ATOMIC_ACQUIRE memory_order_acquire #define __ATOMIC_RELEASE memory_order_release #define __ATOMIC_ACQ_REL memory_order_acq_rel #define __ATOMIC_SEQ_CST memory_order_seq_cst // 封装GCC原子内置函数为MSVC对应实现 #define __atomic_load_n(ptr, order) _Atomic_load_n((ptr), (order)) #define __atomic_store_n(ptr, val, order) _Atomic_store_n((ptr), (val), (order)) #define __atomic_add_fetch(ptr, val, order)_Atomic_fetch_add((ptr), (val), (order)) #define __atomic_sub_fetch(ptr, val, order)_Atomic_fetch_sub((ptr), (val), (order)) #define __atomic_exchange_n(ptr, val, order) _Atomic_exchange_n((ptr), (val), (order)) #define __atomic_compare_exchange_n(ptr, expected, desired, weak, success_order, failure_order) \ _Atomic_compare_exchange_n((ptr), (expected), (desired), (weak), (success_order), (failure_order)) // 其他需要的GCC原子函数可按此逻辑补充 #endif
注意事项:
- 需确保项目启用C11及以上标准(项目属性 → C/C → 语言 → C++标准,选择对应版本)
- MSVC对
memory_order_consume的支持有限,若遇到兼容性问题,可替换为memory_order_acquire - 部分GCC特有原子操作(如复杂内存屏障
__atomic_thread_fence)可直接替换为MSVC的_Atomic_thread_fence
方案2:用C++标准库<atomic>完全替代GCC内置函数
如果代码允许修改,直接使用C++标准原子库是更优雅的跨平台方案,完全无需依赖编译器内置函数:
原GCC代码:
int atomic_val = 0; // 原子加操作 int new_val = __atomic_add_fetch(&atomic_val, 1, __ATOMIC_SEQ_CST);
替换为MSVC兼容的标准库代码:
#include <atomic> std::atomic<int> atomic_val(0); // 原子加操作 int new_val = atomic_val.fetch_add(1, std::memory_order_seq_cst);
优势:
- 完全符合C++标准,无需维护编译器适配宏
- MSVC(v143)对C++11及以后的
<atomic>支持完整,性能与编译器内置函数相当 - 若为C语言项目,可使用MSVC支持的C11标准
<stdatomic.h>头文件,语法与C++标准库类似
方案3:针对特殊原子操作的手动模拟
若遇到极少数无直接MSVC对应函数的GCC原子操作(如某些位操作),可使用MSVC的Interlocked系列函数手动封装,例如:
// 模拟GCC的__atomic_and_fetch #ifdef _MSC_VER #define __atomic_and_fetch(ptr, val, order) _InterlockedAnd((long long*)ptr, (long long)val) #endif
注意:此类封装需确保内存序符合预期,Interlocked系列默认对应memory_order_seq_cst,若需要更宽松的内存序,需结合内存屏障函数_ReadBarrier()/_WriteBarrier()调整。
内容的提问来源于stack exchange,提问作者Sungwoo Lee
相关产品推荐
相关产品推荐

