2

ACCESS_ONCELinuxマクロに相当するものをc++11 に実装しようとしています。ACCESS_ONCE(x)xのアドレスを取得し、xと同じタイプの揮発性オブジェクトへのポインターにキャストしてから、それを逆参照します。これにより、コンパイラはこのマクロを介したxへのアクセスを最適化しないように強制されます(そして、アクセスがここで1回だけ発生するようにします)。

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)))

ポインタを間接参照すると、参照になります。void *& volatileマクロは、あなたが望むようなものではなく、それをキャストしようとしていvoid * volatileます。揮発性修飾子を参照型に適用することはできないため、std :: remove_referenceを使用して、通常の非参照型に変更する必要があります。

于 2012-09-12T17:42:19.600 に答える