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

咨询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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:00:41