I have seen this pattern pop up in some code I am working with and i understand what its intention is, and i understand why people like it but there is something about it that doesn't sit right with me. The pattern is the Guard class. The idea is you have some critical section which you preceed by creating an instance of Guard g(somemutex) which acquires (or attempts to acquire) the somemutex, then when g goes out of scope it release the mutex in g's destructor. This is really cool because it lets you put in returns anywhere in the functions and not need to worry about remembering to release the lock.
My concern is with optimization. If the items in the critical section are marked as volatile then the compiler can not move them across the function call of the constructor. Similarly if the item is veiwable outside the compileation unit (ie if a class has a public member, that member may reasonably changed outside the unit in which it is defined.) the compiler can not assume it can move the item. HOWEVER if the item is private to a class and not declared volatile then there is no reason for the compiler to think that any code outside the compilation unit can affect it, and there is no reason to believe that it must appear before or after the constructor of Guard. for instance:
void foo(int i){
Guard<mutex> g(mymutex);
notVolatilePrivateVar = i;
}
//gets compiled to look like...
void foo(int i){
notVolatilePrivateVar = i;
Guard<mutex> g(mymutex);
}
Now I am not asking if it is likely to happen, i am asking if there is a guarantee that is can not happen.
Similarly with multiple issue cpu's such things could happen, but i would think that it is even less likely to occur because the cpu doesn't know anything at all about the variables or what the function is.
EDIT: I have previously read that question Compiler reordering around mutex boundaries? but it doesn't address my qualm exactly. In that instance _field is a variable that is of unknown scope. In this case the scope is known. The variable is a private member of the class. In this case the only way to modify it is by calling public functions of the class. There is no way that the guard class can possibly have a pointer or reference to the calling function because we don't pass it into the constructor, this means the compiler can know with certainty that creating g can not modify the variable. Indeed it doesn't modify it.