2013-10-29 12 views
10

私はatomic_flagを使用してスピンロックを実装しようとしています。 C++ 11では、atomic_flag変数を初期化する必要がありますが、コンパイルすることはできません。私は「構文エラー:不足している 『を取得したコードをコンパイルするとatomic_flag変数がクラスのメンバーである場合、その変数を初期化するにはどうすればよいですか?

class SpinLock 
{ 
public: 
    SpinLock() 
    :m_flag(ATOMIC_FLAG_INIT) /// syntax error : missing ')' before '{' 
    { 
    } 

    void lock() 
    { 
    while (m_flag.test_and_set() == true){} 
    } 

    void unlock() 
    { 
    m_flag.clear(); 
    } 

private: 
    SpinLock &operator=(const SpinLock &); 

private: 
    std::atomic_flag m_flag; 
}; 

:」『{』の前に』)私のコードは次のようになります。 ATOMIC_FLAG_INITは{0}として定義されていますが、これを記述する正しい方法は何ですか?

以下はコンパイルされますが、まだスレッドセーフですか?

SpinLock() 
    { 
     m_flag.clear(); 
    } 
+1

あなたがコンパイラを使用していますか?あなたのコードはうまくコンパイルする必要があります。 – inf

+1

これはMSVC 2013 RCおよびRTMではコンパイルされません。 (それはしかしプレビューでコンパイルしました)。私はhttp://connect.microsoft.com/VisualStudio/feedback/details/800243/visual-studio-2013-rc-std-atomic-flag-regressionに接続バグを提出しましたが、聞いたことがありません。私のコードでは、私のコードでは、std :: atomic を使用し、test_and_setを交換(true)と置き換えてストア(false) –

+0

私はVisual Studio 2012を使用しています –

答えて

11

のVisual Studio 2012はそれはしかし

Uniform Initialization docsに "initializer_listコンストラクタ" の項を参照)、Visual Studioの2013年にはサポートされているC++ 11の初期化子リスト( see the c++11 support page

をサポートしていません。

一方、あなたのケースでは、コンストラクタは、単に割り当てを使用することができますm_flag = ATOMIC_FLAG_INIT;

更新: 上記の割り当てをテストしなかったようですが、m_flag.clear();を使用すると同じ結果が得られます

+6

ここでの問題は 'atomic_flag'に代入演算子がないため、コンストラクタ本体で' ATOMIC_FLAG_INIT'フラグを初期化することもできません。正しい方法は、デフォルトのコンストラクタ(状態を指定しないまま)を使用してフラグを初期化し、 '.clear()'を呼び出して状態を設定することです。これは確かにVS実装の厄介なバグです。 – ComicSansMS

+0

私はこのようにしようとしていますが、フラグの初期化が依然としてスレッドセーフであるかどうかはわかりません –

+0

あなたはまだSpinLockコンストラクタに入っているので、オブジェクトに「まだ存在しません。 –

1

実際はバグのようです(visual 2013 rtm)。 ATOMIC_FLAG_INITは実装固有のもので、マクロとして{0}に解決されます。つまり、Microsoftは集約ルールを使用してジョブを実行します。

それらについてのcppreferenceからの引用:Until C++11, aggregate initialization could not be used in a constructor initializer list due to syntax restrictions.。私はMicrosoftがまだこの動作を変更していないと結論づけます。ここで

exemple打ち鳴らすには正常に動作し、シンプルなケースでVS2013 RTMに失敗:

struct Pod { 
    int m_val; 
}; 

Pod g_1{ 0 }; // aggregate initialization 
Pod g_2{ { 0 } }; // just like ATOMIC_FLAG_INIT 

struct Foo { 
    Foo() : m_2 { 0 } {} // error C2664: 'Pod::Pod(const Pod &)' : cannot convert argument 1 from 'int' to 'const Pod &' 
    Pod m_1{ 0 }; // error C2664: 'Pod::Pod(const Pod &)' : cannot convert argument 1 from 'int' to 'const Pod &' 
    Pod m_2; // ok 
}; 
関連する問題