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

问题描述 投票:5回答:1

通过我阅读标准,*(_Atomic TYPE*)&(TYPE){0}(用文字表示,将指向非原子的指针转换为指向相应原子和解除引用的指针)不受支持。

如果TYPE不是无锁,那么gcc和/或clang是否将其识别为扩展名? (问题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));
}

现在,如果我用-DSTRUCT编译上面的代码片段,gcc和clang都会保持struct和它的原子变体的大小相同,并且它们会为商店生成一个名为__atomic_store的函数的调用(通过与-latomic链接来解析)。

如果在_Atomic版本的结构中没有嵌入锁,这是如何工作的? (问题2)

c gcc clang atomic c11
1个回答
4
投票

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

如果对齐是正确的,那么使用__atomic builtins更合适,它就是针对这个用例而设计的:

如上所述,这在ABI为普通(非原子)类型提供不充分对​​齐的情况下不起作用,并且_Atomic将改变对齐的情况(目前仅与Clang一起)。

这些内置函数也适用于非原子类型,因为它们使用外部锁。这也是使用相同机制的_Atomic类型不需要额外存储的原因。这意味着由于无意中共享锁而存在一些不必要的争用。如何实现这些锁是一个实现细节,可能会在未来版本的libatomic中发生变化。

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

© www.soinside.com 2019 - 2024. All rights reserved.