I have a lock class like this:
class Mutex {
Guard lock(); // acquire the lock
}
class Guard {
~Guard(); // release the lock
}
This is how I'm using it now:
Mutex m_mutex;
T m_data;
T get_data() {
auto guard = m_mutex.lock();
return m_data;
}
But I'm thinking is it safe / good practice to write like this?
T get_data() {
return (m_mutex.lock(), m_data);
}
CodePudding user response:
It is mostly safe.
The order of destruction has been clarified with CWG 1885, so that the temporary object materialized from the m_mutex.lock()
call will be destroyed only after the result object of the function has been initialized.
The built-in comma operator also guarantees that the left-hand operand is sequenced before the right-hand one.
There is however a problem if there is a operator,
overload for T
. In that case the expression could have any effect. To avoid issues with that you need to explicitly cast the lock expression to void
, which forces use of the built-in comma operator:
return ((void)m_mutex.lock(), m_data);
Whether this is good practice goes into opinion territory, but I think there are definitively going to be many developers who will be confused by this construct for a moment (even if they know how the comma operator and lifetimes work) and it doesn't really save you anything. (Having to choose an unused name is annoying, but not a real issue.)