Yes, the lock will prevent concurrent access but will it prevent the compiler from optimizing away the read completely since main() was the last function that wrote to the variable. I've seen nasty optimization bugs like that happen in C with single threading and strict pointer aliasing and they are not easy to track down.
One could interpret his example program like this (unrolled and tweaked a bit).
int data = 0; //ok data is now guaranteed to be equals to 0
thread t(produce, &data); //called thread with a pointer to data so if i want to read data again i must invalidate my registers
{
lock_guard<mutex> lock(theLock);
data = 5; // i know i set data to 5 here
}
this_thread::sleep_for(chrono::milliseconds(500)); // call contains no references to data, sleep is a "pure" call
{
lock_guard<mutex> lock(theLock); // call contains no references to data
if (data == 5) // i set data to 5 myself, and i haven't done anything that could touch data since then so we optimize away this branch
cout << "data is 5";
}
Will the call to lock_guard simply disable all such kind of optimizations? Or are you required to write memory barriers yourself in some way? I guess a simple way to look at it would be that the compiler assumes that thread will keep the pointer to data and that lock_guard has access to that pointer behind the scenes somehow, so that acquiring the mutex "invalidates" your last write, but that would mean acquiring any mutex would invalidate all variables as the mutex doesn't specify which data-sets it is locking. Am i thinking correctly? Where can i find more information regarding this.