Consider the following code:
#include <atomic>
extern std::atomic<int> i;
void f(void)
{
while (!i.load(std::memory_order_relaxed))
;
}
I'm looking for a citation from the C++11 standard that says that the compiler is not allowed to transform the loop into
if (!i.load(std::memory_order_relaxed)) {
while (1)
;
}
I've seen some discussion here but nothing conclusive.
Edit: A previous version of this post called an extern function inside the loop.
Edit 2: For motivation: The book "Effective Java" says that the HotSpot VM performs the following transformation:
while (!done)
i++;
to
if (!done)
while (true)
i++;
even though it's perfectly defined behavior for another thread to change the done variable concurrently.
Forget about relaxed, there's no guarantee that an atomic store ever become visible to an atomic load in a different thread. The best you get is the normative encouragement in [atomics.order]/12 (and analogous wording in [intro.progress]/18):
...which is not a requirement.
(C11 has identical wording in §7.11.3/16)
Since hoisting the load leads to behavior indistinguishable from a non-hoisted load where the store never becomes visible, and since the latter is conforming, an implementation is allowed by the as-if rule to hoist the load regardless of the memory order used.