【发布时间】:2019-03-05 19:58:08
【问题描述】:
如果我有类型
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;
}
【问题讨论】:
-
根据port70.net/~nsz/c/c11/n1570.html#6.7.2.4p3,
_Atomic与enum一起使用没有任何预防措施。 -
旁注:如果您所做的只是
atomic_store和atomic_load,您可以只声明_Atomic(enum foo) foo_a;,然后使用正常的读取/分配; IIRC,_Atomic合格类型自动执行顺序一致的读/写(匹配普通的atomic_load/atomic_store,它们也是顺序一致的)。如果声明_Atomic、foo = BAR;和enum foo val = foo;仍将是原子操作。我对此不是 100% 确定(inc/dec/compound 分配都绝对是顺序一致的;可能不太严格的语义用于普通读/写)。 -
@ShadowRanger: AFAIK,你总是需要使用
atomic_store_explicit(..., memory_order_release)任何时候你想要比 seq_cst 弱的排序。没有办法让++或=默认为acq/rel 或relaxed 而不是seq_cst。 -
@PeterCordes:是的,我就是这么想的。在第一次检查时没有发现对普通加载和存储的保证,仅适用于读取-修改-写入操作,但即使对于最简单的操作,如果他们谨慎行事,我也不会感到惊讶。
-
@ShadowRanger:gcc / clang 可能只是在不需要时选择了该行为;我没有检查标准。