2016-03-31 7 views
6

shared_ptr実装ではvolatileの比較機能がないようです。C++では、揮発性のshared_ptrとnullptrを比較できますか?

存在するのは理にかなっていますか?

+5

「volatile」は移植可能なスレッド同期メカニズムではないことに注意してください(おそらく一部の環境では十分かもしれません)。通常はメモリマップされたI/Oと同様のメカニズムと共に使用され、これは 'shared_ptr'のための不思議な場所です。たぶん*あなたが揮発性のshared_ptrを持つ理由を明らかにするべきでしょう。 – peterchen

+3

@peterchen http://cxx.isvolatileusefulwiththreads.com/ –

+0

@MikeVine:優秀!そのリンクを覚えています。(変更があった場合は毎日確認してください) – peterchen

答えて

4

本質的には、comparisonsまたはboolean conversionvolatile shared_ptrでは標準が満たされていません。

コンパイルするfollowing fails ...

auto main() -> int { 
    volatile shared_ptr<int> a; 
    if (a == nullptr) // fails 
     ; // empty 
    if (a) // fails 
     ; // empty 
} 

あなたは(経由。const_castvolatileオフを唱えたが、私はそれが望ましい結果を持っていますかわかりません。 cppreferenceから:

constアクセス経路を通してconstオブジェクトを変更し、未定義の動作に非volatile glvalue結果を通じてvolatileオブジェクトを参照します。それはあったが、その後、適切な方法や場合 - volatileとしてメンバメソッドをマークしないで、クラスやライブラリ実装者が効果的に「これはvolatileオブジェクトとして使用することを意図するものではない」と言っているより一般的に言えば

、オーバーロードはvolatile個のオブジェクトを提供します。同様に、これはconstとしてメンバーをマークするには、constに適用され、彼らは「このクラスはconstオブジェクトとして使用することができます。

がなぜ必要なvolatile、外部のどのようなソースがshared_ptrを変更することができている」と言っているの知識がなくても(これはvolatileの使用の1つです)スレッドの問題がある場合は、スレッドライブラリユーティリティを使用する方が良いでしょう。あるいは単に最適化をオフにしているだけの場合は、さまざまなコンパイラがこれについてのメカニズムを持っています(プラグマなど)。

+0

良い点ですが、std :: atomicを使用するのはC++ 11で揮発性より完璧です。 – Atifm

3

Volatileは、予期せずメモリが変更される可能性があることをコンパイラに示すものです。いくつかの最適化を無効にします。その下にはちょうどメモリアドレスが含まれています。

共有ポインターはリソースを保持/管理しているだけです。つまり、std :: shared_ptr :: get()はvolatileとマークされていないので、実際にはshared_ptrを使用してアクセス可能な方法でvolatileポインタを管理することはできません。

裸のポインタを使用し、スコープ付き出口またはデストラクタを使用してその後ろをクリーンアップすることをお勧めします。

volatileを使用していて、ポインタが別のスレッドによって変更される可能性がある場合は、volatileの代わりにstd :: atomicを使用することをお勧めします。スレッドのワークフローでは、std::atomicの前に、他のスレッドからアクセスされたポインタは通常volatileとマークされました。それはもはやベストプラクティスではありません。

+0

実際には揮発性は示唆ではありません。それが行うことの1つは、揮発性オブジェクトのすべてのアクセス(読み取りまたは書き込み操作、メンバー関数呼び出しなど)は、最適化の目的で目に見える副作用として扱われます(つまり、 – NathanOliver

+1

この関数には揮発性の修飾子がないので、volatileオブジェクトで呼び出すことはできません.... – cpplearner

+0

@nathanOliverはあなたの提案通りに改名しました。 – Atifm

関連する問題