次のコードを検討してください。
void ListenerImpl::attach(boost::shared_ptr<ISubscriber> subscriber)
{
boost::unique_lock<boost::mutex>(mtx);
subscribers.push_back(subscriber);
}
void ListenerImpl::notify(MsgPtr msg)
{
boost::unique_lock<boost::mutex>(mtx);
//notify all subscribers
BOOST_FOREACH(boost::shared_ptr<ISubscriber> subscriber, subscribers){
subscriber->update(msg);
}
}
(これは、GoFで説明されているオブザーバーパターンの実装です。)ここでのユーザー介入は、attach()とnotify()を同時に実行しないように保護することでした。したがって、boost::unique_lockです。目標は、subscribers
コンテナを保護することでした。
しかし、ロックが実際には一時的なものであることに気付くのは非常に困難です(詳しく見てみると、名前は割り当てられていません)。したがって、一時的なものが破棄されると、ミューテックスのロックはすぐに解放されます。つまり、コードはスレッドセーフではありません。このような状況では、コンパイラの警告が予想されます。「未使用の一時的」のようなもの。
さらに悪いことに、cppcheckはこの間違いも認識しません。(cppcheck:ac / c ++コード分析ツールhttp://sourceforge.net/apps/mediawiki/cppcheck/index.php?title=Main_Page)
Gccは、未使用の変数に対して警告を発行します。ここでの一時的な変数は未使用の変数であり、間違いなくプログラマーの不注意の結果です。では、なぜこのような場合に警告がないのでしょうか。たぶん、そのような状況を発見するのは複雑すぎますか?