In which cases compiler can reorder instructions by its own will?
For example, can they be reordered in case when synchronization primitives like mutexes are involved like in the following example:
void foo()
{
int x = 0;
{
std::lock_guard<std::mutex> lock(g_mutex);
std::cout << x << std::endl;
}
x = 1;
}
Can this code print 1 instead of 0 at some conditions?
And will any shared variables be actually modified after calling unlock
on such mutex so it's guaranteed that other threads will see the updated values of such variables instead of the probably-cached ones?
Does it apply to all well-known synchronization primitives like critical sections, mutexes etc?
Is it also guaranteed that the following code (assuming that Thread 1 will acquire the specified mutex before Thread 2) will always print 1 instead of some cached value (for example, 0):
int some_global_variable = 0;
// Thread 1
mutex.lock();
some_global_variable = 1;
mutex.unlock();
// Thread 2
mutex.lock();
std::cout << some_global_variable << std::endl;
mutex.unlock();
If so, why? Where does it stated?