传递给原子操作的
std::memory_order
类型的参数会影响编译时和运行时。不过,我想知道这个类型是否是编译器的特殊标记。换句话说,当给定具有相同值的用户定义类型时,例如
#include <atomic>
enum my_memory_order{
release = (int)std::memory_order::release,
};
int main(){
std::atomic<int> v = {0};
v.store(1,(std::memory_order)my_memory_order::release); // #1
}
用户定义的枚举
my_memory_order
是否能够被编译器识别并在编译时发出相同的代码,就像传递的参数是 std::memory_order::release
一样?或者,std::memory_order
是编译器赋予特权的特殊标签?
另一个问题是,编译器如何知道代码是否应该根据提供的
std::memory_order
重新排序?例如:
void show(std::memory_order){
/// balabala
}
int main(){
int x;
std::memory_order ordering;
ordering = /*runtime value*/;
x = 1;
show(ordering);
}
编译器是否看到这个函数有一些类型为
std::memory_order
的参数,因此它会发出一些分支来根据重新排序语义生成代码?
如果这个类型是编译器的特殊标签
类型为
int
。没有人知道这是否“特别”。可能是这样。
在 gcc 上描述了原子的语义https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html。您可以猜测 std::memory_order::release
的
value映射到
__ATOMIC_RELEASE
。
用户定义的枚举 my_memory_order 是否被编译器识别并在编译时发出相同的代码,就像传递的参数是 std::memory_order::release 一样?
如果
(int)std::memory_order::release
正确保留该值,则可以。
std::memory_orders 是编译器赋予特权的特殊标签?
不知道/没有人知道/取决于实际实现和“特殊标签”的定义。
编译器如何知道代码是否应该根据提供的 std::memory_order 重新排序?
它完全依赖于编译器。 在 gcc 上,当您调用像
__atomic_store_n
这样的内置函数时,编译器会分析调用树并从用户编写的代码中推断其信息。
编译器是否看到这个函数有一些类型为 std::memory_order 的参数,因此它会发出一些分支来根据重新排序语义生成代码?
再次强调,完全依赖于编译器。 在 gcc 上 文档指出:
请注意,C++11 标准允许在运行时而不是编译时确定内存顺序参数。这些内置函数将任何运行时值映射到 __ATOMIC_SEQ_CST,而不是调用运行时库调用或内联 switch 语句。这是符合标准、安全且目前最简单的方法。
编译器是否看到这个函数有一些类型为 std::memory_order 的参数,因此它会发出一些分支来根据重新排序语义生成代码?
没有。