将指针转换为_Atomic指针和_Atomic大小

PSk*_*cik 5 c gcc atomic clang c11

根据我对标准的阅读, *(_Atomic TYPE*)&(TYPE){0}(不支持将指针转换为非原子指针,将指针转换为对应的原子并取消引用)。

如果gcc和/或clang TYPE不无锁,是否会将其识别为扩展?(问题1)

第二个相关问题:我给人的印象是,如果TYPE不能将其实现为无锁原子,那么就需要在相应的中嵌入锁_Atomic TYPE。但是,如果我做TYPE一个相当大的结构,然后在两个clanggcc它的大小与相同_Atomic TYPE

这两个问题的代码:

#include <stdatomic.h>
#include <stdio.h>

#if STRUCT
typedef struct {
    int x;
    char bytes[50];
} TYPE;
#else
typedef int TYPE;
#endif

TYPE x;

void f (_Atomic TYPE *X)
{
    *X = (TYPE){0};
}

void use_f()
{
    f((_Atomic TYPE*)(&x));
}

#include <stdio.h>
int main()
{
    printf("%zu %zu\n", sizeof(TYPE), sizeof(_Atomic TYPE));
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我使用编译上面的代码段-DSTRUCT,gcc和clang都将struct和它的atomic变量都保持在相同的大小,并且它们生成__atomic_store对以商店命名的函数的调用(通过与链接解决-latomic)。

如果_Atomic该结构的版本中未嵌入任何锁,该如何工作?(问题2)

Flo*_*mer 4

_Atomic改变了 Clang 上某些极端情况的对齐方式,并且 GCC 也可能在未来得到修复(PR 65146)。在这些情况下,_Atomic通过强制转换添加不起作用(从 C 标准的角度来看,这很好,因为正如您所指出的,这是未定义的行为)。

如果对齐正确,则使用__atomic内置函数更合适,它们是专门针对此用例而设计的:

如上所述,在 ABI 为普通(非原子)类型提供的对齐方式不足以及_Atomic需要更改对齐方式(目前仅使用 Clang)的情况下,这将不起作用。

这些内置函数也适用于非原子类型,因为它们使用外线锁。_Atomic这也是使用相同机制的类型不需要额外存储的原因。这意味着由于无意共享锁而导致一些不必要的争用。这些锁的实现方式是一个实现细节,在libatomic.

一般来说,对于具有涉及锁定的原子内置函数的类型,将它们与共享或别名内存映射一起使用是行不通的。这些内置函数也不是异步信号安全的。(无论如何,所有这些功能在技术上都超出了 C 标准。)