`std::memory_order`是编译器在编译时的特殊标签吗?

问题描述 投票:0回答:1

传递给原子操作的

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
的参数,因此它会发出一些分支来根据重新排序语义生成代码?

c++ atomic memory-barriers stdatomic
1个回答
0
投票

如果这个类型是编译器的特殊标签

类型为

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 的参数,因此它会发出一些分支来根据重新排序语义生成代码?

没有。

© www.soinside.com 2019 - 2024. All rights reserved.