2016-07-05 13 views
3

私は自分の原子クラスを特定のプロジェクトのように実装しています私はC++ 11の原子ライブラリにアクセスできない。私は、次のコードを持って、これまで:戻り値レジスタとデストラクタの呼び出し順

class CAtomicLong 
{ 
public: 

    CAtomicLong(long lVal) : m_lValue(lVal) {} 

    long operator+(long lVal) 
    { 
     CAutoLock lock(m_lock); 
     m_lValue += lVal; 
     return m_lValue; 
    } 
private: 

    CMyMutex m_lock; 
    long m_lValue; 
}; 

CMyMutexは、ミューテックスの周りにカスタムラッパーで、CAutoLockはそのデストラクタその構築の間にそれに渡されたオブジェクトのロックを解除したクラスであると仮定します。これらの詳細は、とにかくこの質問にはほとんど関係しません。

私が知りたいのは、このようにm_lValueを返すことが安全かどうかです。つまり、を返すためにレジスタにコピーされます。の前に、デストラクタlockが呼び出されますか?デストラクタがの前にと呼び出された場合、戻りレジスタが設定されているため、別のスレッドが復帰のためにコピーされているようにm_lValueを変更する可能性があるためです。

私はこのようなコードをVisual Studioで解体を見て持っていたし、デストラクタが呼ばれる前に行われてリターンコールを示すように見えるが、a)は、私は本当に私は何を知っていません(私はまだ学んでいる:))とb)これは標準的な動作かどうかわからない(もう一度、私はまだ学んでいる)。この潜在的な問題の最も安全な回避策は

long operator+(long lVal) 
{ 
    CAutoLock lock(m_lock); 
    long lTemp = (m_lValue += lVal); 
    return lTemp; 
} 

です...しかし、これは行き過ぎである場合、私はむしろ、今知っていると思います。

+1

あなたはどのプラットフォームにいますか?それらのほとんどは原子増分とフェッチのための本質を持っています。これはmutexの代わりに使用することができます – Dani

+0

これはWindows、Solaris Sparc、およびLinuxで動作する必要があります。私はWindows上に原子インクリメント関数があることは知っていますが、アトミック検索関数を見つけることはできませんし、Solaris上で必要な関数にアクセスすることもできません。したがって、この質問。 – Wad

+0

C++には「レジスタ」はありません。コードは書かれているとおりに正しいです。 –

答えて

5

コードは正しいです。 [stmt.return]/3氏は述べています:

呼び出しの結果のコピー、初期化がreturn文のオペランドによって確立された完全な式の終わりに一時の破壊の前に配列決定されていますは、 の前に、return文を囲むブロックのローカル変数(6.6)が破棄される前にシーケンスされます。

関連する問題