C11 stdatomic 和 calloc

C11 stdatomic and calloc

我有一个包含原子字段的结构:

#include <stdatomic.h>

struct s {
    ...
    atomic_int a;
};

此结构分配有calloc:

struct s *p = calloc(1, sizeof(struct s));

期望p->a初始化为0是否可移植?代码中有足够的障碍,因此弱一致初始化是可以的,但是初始值是否保证为 0?

我猜这不是 portable/safe。

很可能 calloc() 最终在内存区域做了一个简单的 memset()。这个简单的 memset() 不会发出所需的内存屏障来确保读取该结构的其他线程会将 p->a 视为 0.

struct s *p = calloc(1, sizeof(struct s));
struct s *q = p;
// some other thread
foo(*q);

p 或其任何助手可以访问内存之前,将初始化为零。是0.

另见 deferred 归零。

不,这一般是不可移植的。 calloc 仅保证基础对象的字节 0 值。对于(可能)具有状态的类型,这不等同于初始化。您肯定必须使用 atomic_init 将您的对象置于有效状态。

这是因为除了基础对象之外还持有 "lock" 的平台,因为它们没有实现相应的汇编程序指令。因此,为了便携,您确实需要对所有非静态分配的原子对象使用 ATOMIC_VAR_INITatomic_init

就是说,我不知道有哪个现有平台会需要这样的东西 atomic_int。如果您的平台将 ATOMIC_INT_LOCK_FREE 设置为 2sizeof(atomic_int)==sizeof(int),您可以相对确定您的策略有效。您可以在 _Static_assert.

中进行测试