The memory location x
is ... written to by thread 2
Is it really? Why do you say so?
If y
is 0 then x
is not written to by thread 2. And y
starts out 0. Similarly, x
cannot be non-zero unless somehow y
is non-zero "before" thread 1 runs, and that cannot happen. The general point here is that conditional writes that don't execute don't cause a data race.
This is a non-trivial fact of the memory model, though, because a compiler that is not aware of threading would be permitted (assuming y
is not volatile) to transform the code if (x) y = 1;
to int tmp = y; y = 1; if (!x) y = tmp;
. Then there would be a data race. I can't imagine why it would want to do that exact transformation, but that doesn't matter, the point is that optimizers for non-threaded environments can do things that would violate the threaded memory model. So when Stroustrup says that every compiler he knows of gives the right answer (right under C++11's threading model, that is), that's a non-trivial statement about the readiness of those compilers for C++11 threading.
A more realistic transformation of if (x) y = 1
would be y = x ? 1 : y;
. I believe that this would cause a data race in your example, and that there is no special treatment in the standard for the assignment y = y
that makes it safe to execute unsequenced with respect to a read of y
in another thread. You might find it hard to imagine hardware on which it doesn't work, and anyway I may be wrong, which is why I used a different example above that's less realistic but has a blatant data race.