咨询C17标准中原子类型的非弃用初始化方法
在C17中正确初始化原子类型的方式
好问题!在C17标准弃用ATOMIC_VAR_INIT之后,原子类型的初始化其实变得更简洁直观了,大部分场景下和非原子类型的初始化方式完全一致,只有动态分配的情况需要用到专门的函数。下面分三种常见场景说明:
1. 静态/线程局部存储期的原子变量
对于全局、静态或者_Thread_local修饰的原子变量,直接用常规的赋值初始化就行,编译器会保证这个初始化过程是原子性的,完全符合标准要求:
#include <stdatomic.h> // 全局原子变量初始化 atomic_int global_counter = 0; void foo() { // 静态局部原子变量初始化 static atomic_bool flag = true; // 线程局部原子变量初始化 _Thread_local atomic_long thread_id = -1; }
这种写法比旧的ATOMIC_VAR_INIT宏(比如atomic_int cnt = ATOMIC_VAR_INIT(0);)更清晰,也是C17推荐的方式。
2. 自动存储期(栈上)的原子变量
栈上的原子变量同样可以直接用初始化器赋值,不需要任何特殊处理:
void bar() { // 直接赋值初始化 atomic_uint stack_val = 123; // 或者用聚合初始化语法(效果一样) atomic_float stack_float = {3.14f}; }
注意:初始化完成后,如果要修改这个原子变量,依然需要使用atomic_store、atomic_fetch_add这类原子操作函数,但初始化本身和普通变量没区别。
3. 动态分配的原子变量
如果是用malloc、calloc等函数分配的原子变量,因为内存是未初始化的,不能直接赋值,这时候必须用atomic_init函数来完成原子初始化:
#include <stdatomic.h> #include <stdlib.h> void dynamic_init_example() { atomic_int *dyn_atomic = malloc(sizeof(atomic_int)); if (dyn_atomic != NULL) { // 用atomic_init初始化动态分配的原子变量 atomic_init(dyn_atomic, 456); } }
atomic_init是C11就引入的函数,C17依然推荐使用它处理动态分配的原子变量,确保初始化过程的原子性和正确性。
补充:为什么弃用ATOMIC_VAR_INIT?
标准委员会认为这个宏是多余的:静态/自动存储期的原子变量可以通过常规初始化语法完成原子初始化,动态分配的有atomic_init专门处理,ATOMIC_VAR_INIT的存在没有必要,所以C17将其标记为弃用,到C23已经完全移除了这个宏。
内容的提问来源于stack exchange,提问作者Wingblade
相关产品推荐
相关产品推荐

