2

我正在尝试ACCESS_ONCE在 c++11 中实现相当于 Linux 宏的功能。 ACCESS_ONCE(x)获取 x 的地址,转换为指向与 x 相同类型的 volatile 的指针,然后取消引用它。这会强制编译器不优化通过此宏对 x 的访问(并使访问仅在此处发生一次)。

我在 c++11 中的尝试包括decltype

#define ACCESS_ONCE(x) (*static_cast<decltype(x) volatile *>(&(x)))

这适用于大多数情况,但我像这样使用它一次:

void foo(void **bar) {
  while (ACCESS_ONCE(*bar) != NULL)
    ;
}

这失败并出现错误:

'volatile' qualifiers cannot be applied to 'void*&'

我究竟做错了什么?

4

2 回答 2

7
template<typename T>
inline T volatile &access_once(T &t) {
    return static_cast<T volatile &>(t);
}

这避免了宏,更简单,因为模板签名中隐含了类型推导和引用删除,并且它避免了冗余的地址和引用运算符(引用类型之间的静态转换被定义为与获取地址、转换和然后取消引用)。它同样高效,我认为它不依赖于 C++11 中的任何内容。

于 2012-09-12T19:38:08.187 回答
5

将宏更改为:

#define ACCESS_ONCE(x) (*static_cast<std::remove_reference<decltype(x)>::type volatile *>(&(x)))

取消引用指针会导致引用。宏正在尝试将其转换为 avoid *& volatile而不是void * volatile您想要的。您不能将 volatile 限定符应用于引用类型,因此您必须使用 std::remove_reference 将其更改为正常的非引用类型。

于 2012-09-12T17:42:19.600 回答