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

时间:2019-03-05 19:58:08

标签: c 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;

    atomic_store(&foo, BAR);

    enum foo val = atomic_load(&foo);

    printf("%u\n", val);

    return 0;
}

2 个答案:

答案 0 :(得分:3)

是的,所有数据类型都可以是原子的,因此不需要使用原子的泛型函数。这样,对此类对象的所有操作都是原子的。

对于第二个示例,奇怪的是编译器未发出警告。对原子操作使用非原子操作会违反约束,因此编译器应为您提供诊断信息。

答案 1 :(得分:3)

是的,这是合法的。顺便说一句,您实际上不需要括号,_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 builtinsvoid __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