I use std::scoped_lock to guard pairs of objects in multi-threading environment. But I found that scoped_lock can lead to deadlock (in Visual Studio and gcc) if both its arguments are the same. For example,
#include <mutex>
struct S
{
mutable std::mutex m;
int v = 0;
S & operator = ( const S & b )
{
std::scoped_lock l( m, b.m );
v = b.v;
return * this;
}
};
int main()
{
S a;
a = a; //deadlock here!
}
I see that the standard requires “The behavior is undefined if one of MutexTypes is not a recursive mutex and the current thread already owns the corresponding argument in ...”, see https://en.cppreference.com/w/cpp/thread/scoped_lock/scoped_lock
But formally in my example the mutex is not locked before scoped_locked. So is it expected program behaviour?