I'm wondering if it is possible to configure the c++ compiler so that it emits a warning when someone instatiates a scoped_lock but forgets to assign it to a variable.
See the examples below:
See code below, I have tested it with g++-4.8 and visual studio 2010. Neither of them detects the faulty case 2.2.
Does anyone know why case 2.2 compiles, and what could be done in order to let the compiler detect it as a warning?
#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);
}
};
This line:
boost::recursive_mutex::scoped_lock(mMutex);
is equivalent to this line:
boost::recursive_mutex::scoped_lock mMutex;
as such, what would the compiler warning or error be? In the first case it's an error because you're trying to redeclare mMutex
, but in the second case it's perfectly reasonable code since scoped_lock
is default-constructible. It's only wrong for the specific logic in your function. The compiler can't read your mind.
If you want to simply prevent a scoped_lock
from being default constructed, you could just make your own that isn't:
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>;
};
That way,
my_recursive_mutex mMutex;
{
my_recursive_mutex::scoped_lock(mMutex);
}
won't compile, since the default constructor is delete
d.