我可以将 C11 `_Atomic` 关键字应用于枚举类型吗?
Can I apply the C11 `_Atomic` keyword to enum types?
如果我有类型
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
与其他类型限定符类似,如 const
和 volatile
.
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
的值。)
所以none这个实际上要求指针类型有_Atomic
.
如果我有类型
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
与其他类型限定符类似,如 const
和 volatile
.
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
的值。)
所以none这个实际上要求指针类型有_Atomic
.