C++/boost::scoped_lock:缺少编译器警告
C++ / boost::scoped_lock : compiler warnings missing
我想知道是否可以配置 c++ 编译器,以便在有人实例化 scoped_lock 但忘记将其分配给变量时发出警告。
请参阅以下示例:
- 案例 1.1 和案例 2.1 显示了 scoped_lock
的预期用途
- 案例 1.2 是错误的使用,其中没有创建 holder 变量。它被编译器正确检测为错误(mMutex 有一个先前的声明)
- 案例2.2和案例1.2几乎是一样的错误,但是编译器没有检测也没有发出任何警告,虽然代码明显错误,并且非常接近案例1.2(当然互斥锁会不工作)。
看下面的代码,我已经用g++-4.8和visual studio 2010测试过。它们都没有检测到错误的情况2.2。
有谁知道为什么案例 2.2 可以编译,可以做什么才能让编译器将其检测为警告?
#include <boost/thread/recursive_mutex.hpp>
void Mutex1()
{
boost::recursive_mutex mMutex;
//Case 1.1 : correct mutex creation
boost::recursive_mutex::scoped_lock lock(mMutex);
//Case 1.2 : incorrect mutex creation
//==> leads to a compile error : "mMutex has a previous declaration" : perfect
boost::recursive_mutex::scoped_lock(mMutex);
}
class FooMutex
{
boost::recursive_mutex mMutex;
void TestMutex()
{
//Case 2.1 : correct mutex creation
boost::recursive_mutex::scoped_lock lock(mMutex);//compiles correctly => ok
//Case 2.2 : incorrect mutex creation
//is compiled without warning ! Ouch !!!
boost::recursive_mutex::scoped_lock(mMutex);
}
};
这一行:
boost::recursive_mutex::scoped_lock(mMutex);
相当于这一行:
boost::recursive_mutex::scoped_lock mMutex;
因此,编译器警告或错误是什么?在第一种情况下,这是一个错误,因为您试图重新声明 mMutex
,但在第二种情况下,它是完全合理的代码,因为 scoped_lock
是可默认构造的。只有你的函数中的特定逻辑是错误的。编译器无法读懂你的想法。
如果你想简单地防止 scoped_lock
被默认构造,你可以自己制作一个不是:
template <typename T>
struct my_unique_lock : boost::unique_lock<T> {
using boost::unique_lock<T>::unique_lock;
my_unique_lock() = delete;
};
struct my_recursive_mutex : boost::recursive_mutex {
using scoped_lock = my_unique_lock<my_recursive_mutex>;
};
这样,
my_recursive_mutex mMutex;
{
my_recursive_mutex::scoped_lock(mMutex);
}
不会编译,因为默认构造函数是 delete
d。
实际上 g++ 可以为此提供警告:-Wshadow
g++ -Wall -Wshadow test.cpp -lboost_thread-mt -l boost_system
参见:C++ Warning if re-declaring member variable in function
对于 clang:-Wshadow-ivar
我想知道是否可以配置 c++ 编译器,以便在有人实例化 scoped_lock 但忘记将其分配给变量时发出警告。
请参阅以下示例:
- 案例 1.1 和案例 2.1 显示了 scoped_lock 的预期用途
- 案例 1.2 是错误的使用,其中没有创建 holder 变量。它被编译器正确检测为错误(mMutex 有一个先前的声明)
- 案例2.2和案例1.2几乎是一样的错误,但是编译器没有检测也没有发出任何警告,虽然代码明显错误,并且非常接近案例1.2(当然互斥锁会不工作)。
看下面的代码,我已经用g++-4.8和visual studio 2010测试过。它们都没有检测到错误的情况2.2。
有谁知道为什么案例 2.2 可以编译,可以做什么才能让编译器将其检测为警告?
#include <boost/thread/recursive_mutex.hpp>
void Mutex1()
{
boost::recursive_mutex mMutex;
//Case 1.1 : correct mutex creation
boost::recursive_mutex::scoped_lock lock(mMutex);
//Case 1.2 : incorrect mutex creation
//==> leads to a compile error : "mMutex has a previous declaration" : perfect
boost::recursive_mutex::scoped_lock(mMutex);
}
class FooMutex
{
boost::recursive_mutex mMutex;
void TestMutex()
{
//Case 2.1 : correct mutex creation
boost::recursive_mutex::scoped_lock lock(mMutex);//compiles correctly => ok
//Case 2.2 : incorrect mutex creation
//is compiled without warning ! Ouch !!!
boost::recursive_mutex::scoped_lock(mMutex);
}
};
这一行:
boost::recursive_mutex::scoped_lock(mMutex);
相当于这一行:
boost::recursive_mutex::scoped_lock mMutex;
因此,编译器警告或错误是什么?在第一种情况下,这是一个错误,因为您试图重新声明 mMutex
,但在第二种情况下,它是完全合理的代码,因为 scoped_lock
是可默认构造的。只有你的函数中的特定逻辑是错误的。编译器无法读懂你的想法。
如果你想简单地防止 scoped_lock
被默认构造,你可以自己制作一个不是:
template <typename T>
struct my_unique_lock : boost::unique_lock<T> {
using boost::unique_lock<T>::unique_lock;
my_unique_lock() = delete;
};
struct my_recursive_mutex : boost::recursive_mutex {
using scoped_lock = my_unique_lock<my_recursive_mutex>;
};
这样,
my_recursive_mutex mMutex;
{
my_recursive_mutex::scoped_lock(mMutex);
}
不会编译,因为默认构造函数是 delete
d。
实际上 g++ 可以为此提供警告:-Wshadow
g++ -Wall -Wshadow test.cpp -lboost_thread-mt -l boost_system
参见:C++ Warning if re-declaring member variable in function
对于 clang:-Wshadow-ivar