c ++ access_once

dsc*_*atz 2 c++ c++11

我正在尝试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)))
Run Code Online (Sandbox Code Playgroud)

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

void foo(void **bar) {
  while (ACCESS_ONCE(*bar) != NULL)
    ;
}
Run Code Online (Sandbox Code Playgroud)

这失败并出现错误:

'volatile' qualifiers cannot be applied to 'void*&'
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

bam*_*s53 7

template<typename T>
inline T volatile &access_once(T &t) {
    return static_cast<T volatile &>(t);
}
Run Code Online (Sandbox Code Playgroud)

这避免了宏,因为类型推导和引用删除隐含在模板签名中,它避免了冗余的地址和引用操作符(引用类型之间的静态转换被定义为执行与获取地址,转换和然后解除引用).它的表现同样出色,我不认为这取决于C++ 11中的任何内容.


Dir*_*ple 5

将宏更改为:

#define ACCESS_ONCE(x) (*static_cast<std::remove_reference<decltype(x)>::type volatile *>(&(x)))
Run Code Online (Sandbox Code Playgroud)

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