2015-11-17 3 views
6

一部の人々はロックが書き込みによる誤使用できることを警告している。代わりに、次の正しい文のC++で一時変数を明示的にインスタンス化することはできますか?

std::unique_lock<std::mutex>(mutex); 

std::unique_lock<std::mutex> lock(mutex); 

すなわち、ローカル変数の代わりに名前のない一時変数を作成します。一時変数はすぐに破棄され、ミューテックスのロックを早めに解除します。

は、インスタンスgperftools (line 321-324) headerを参照してください:

// Catch bug where variable name is omitted, e.g. MutexLock (&mu); 
#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name) 
#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name) 
#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name) 

このマクロは再び、このようなユースケースを保護するために書かれています。

でも、それでも起こりますか?どうやら最近の十分なGCCまたは打ち鳴らすは、この場合にはエラーを生成します:

#include <iostream> 

class Mutex {}; 

class Lock { 
public: 
    explicit Lock(Mutex */* dummy */) { std::cout << __PRETTY_FUNCTION__ << std::endl; } 
    ~Lock() { std::cout << __PRETTY_FUNCTION__ << std::endl; } 
}; 

int main() { 
    Mutex mutex; 
    { 
    Lock l(&mutex); 
    } 
    { 
    Lock(&mutex); // This line does not compile. 
    } 
    return 0; 
} 

とエラー:

g++ foo.cpp 
foo.cpp:17:11: error: declaration of reference variable 'mutex' requires an initializer 
    Lock(&mutex); 
      ^~~~~ 
1 error generated. 

誰かが、そのようなマクロが本当のバグをキャッチしますREPRO場合を示してもらえますか?私はこれまでのところ思い付くことができませんでした。

+1

おそらく関連:http://stackoverflow.com/questions/914861/disallowing-creation-of-the -temporary-objects – BenC

答えて

4

実際には、参照を初期化する必要があるルールと組み合わせて、宣言として表現できるもの(表現ではなく宣言として解析されます)の曖昧さ回避ルールによって保存されています。

それはあなたをここに保存されません。ここに

std::mutex m; 
int main(){ 
    std::unique_lock<std::mutex>(m); // m is a local default-constructed unique_lock 
} 

かを:

struct C { Mutex m; } c; 
int main() { 
    Lock(&c.m); // Constructs and destroys a temporary lock. 
} 
+0

最初の例では、std :: mutexがコンパイルされていない場合にメインの内側にありますが、mutexが外部にある場合は非常に混乱しています。ここでどんな種類のパターンが問題であるかを詳しく説明できますか? –

+0

@ThomasMoulard 'std :: unique_lock (m);'は宣言として解析されるので、 'std :: unique_lock m;と完全に等価です。ミューテックスが 'main'の中にある場合、なぜコンパイルされないのかはかなり明白です。 –

+0

私は愚かな気分になりました;)ありがとう! –

関連する問題