我可以将 C11 `_Atomic` 关键字应用于枚举类型吗?

标签 c enums c11 stdatomic

如果我有类型

enum foo {
    FOO,
    BAR,
    BAZ,
};

然后我可以声明该类型的原子版本吗

_Atomic(enum foo);

或者我必须使用例如atomic_int 并转换 atomic_load() 的结果?

以下程序编译时没有警告:

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

    enum foo {FOO, BAR, BAZ};

    int main(void) {
        _Atomic(enum foo) foo_a;
        atomic_store(&foo_a, BAR);
        enum foo val = atomic_load(&foo_a);
        printf("%u\n", val);
        return 0;
    }

但也是如此:

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

    enum foo {FOO, BAR, BAZ};

    int main(void) {
        enum foo foo; // <---- non atomic
        atomic_store(&foo, BAR);
        enum foo val = atomic_load(&foo);
        printf("%u\n", val);
        return 0;
    }

最佳答案

是的,这是合法的。顺便说一句,你实际上并不需要括号,_Atomic enum foo foo;是等价的。

_Atomic像其他类型限定符一样工作,比如 constvolatile .


enum foo foo;
atomic_store(&foo, BAR);

是 clang 的错误error: address argument to atomic operation must be a pointer to _Atomic type ('enum foo *' invalid) . (来自 the Godbolt compiler explorer)。


这只是 GCC 实现的一个怪癖,它甚至在没有警告的情况下编译,即使在 -Wall。 .这可能应该改变......

GCC's atomic builtins喜欢void __atomic_store_n (type *ptr, type val, int memorder)获取指向普通类型的指针,而不需要 _Atomic .

C++11 <atomic>使用这些内置函数。同样,GCC 的 C11 stdatomic.h使用

#define atomic_store_explicit(PTR, VAL, MO)                             \
  __extension__                                                         \
  ({                                                                    \
    __auto_type __atomic_store_ptr = (PTR);                             \
    __typeof__ (*__atomic_store_ptr) __atomic_store_tmp = (VAL);        \
    __atomic_store (__atomic_store_ptr, &__atomic_store_tmp, (MO));     \
  })

#define atomic_store(PTR, VAL)                          \
  atomic_store_explicit (PTR, VAL, __ATOMIC_SEQ_CST)

(__extension__ 用于 GNU C 语句表达式,其中 x = {foo; bar;}bar 的值。)

所以这些实际上都不需要指针类型有 _Atomic .

关于我可以将 C11 `_Atomic` 关键字应用于枚举类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55010595/

相关文章:

c - 在 C 中使用管道传递多个数据 block

C fork 函数在 Unix (HP-UX) 上的奇怪行为

java - Hibernate 枚举转换和转换器映射

java - 如何在 Java 中使用动态值调用枚举方法

c - 使用C scanf_s的字符串输入

multithreading - 什么是潜在共享内存位置?

c - 安装 c api (md5)

C 构建错误 "Expected int(*)[10] but argument is of type ' int'"

c# - 公开基础库中定义的枚举类型

c - 条件运算符的评估顺序