It is not relevant whether or not the equivalent access on the ISA level is atomic. You can't violate the C++ memory model. The compiler will optimize under the assumption that it is not violated.
In particular only std::atomic
specializations are atomic types in the C++ model. Any unsynchronized access to any other object type (with at least one a write) is a data race in the C++ model and therefore causes undefined behavior.
Therefore it is required here to lock the mutex before reading the variable if x
's type is not a std::atomic
specialization. However if so, this could be avoided by making x
an std::atomic
instead. Then it would not cause a data race, regardless of whether the equivalent access on the ISA level is atomic. (The compiler has to implement atomicity with locks inside std::atomic
if the hardware doesn't support it directly.)
That being said, as you are hinting at, it doesn't seem that the function is particularly useful. As soon as it returns, the value of x
might have already changed, so the caller can not assume it to still hold that value. However, without the locking the code will have undefined behavior, which is a worse condition than just providing a useless value.