Absolutely.
Since x not marked as volatile and seems to be a local object with automatic storage time and internal communication, and the program does not change it, both programs are equivalent.
In both C ++ 03 and C ++ 11, this is done according to the as-if rule, since access to a non-volatile object is not considered a βside effectβ of the program:
[C++11: 1.9/12]: Access to an object indicated by a mutable glvalue (3.10), modifying an object, calling a library I / O function, or calling a function that makes any of these operations all side effects that change state of the environment fulfillment. Evaluating an expression (or subexpression) generally includes both calculating the values ββ(including determining the identity of the object to evaluate the glvalue and fetching the value previously assigned to the object to evaluate the evaluation) and triggering side effects. When a call to a library I / O function is returned or access to a volatile object is calculated, the side effect is considered complete, even if some external actions are implied by a call (for example, I / O itself) or unstable access may not be completed.
C ++ 11 frees up space for a global object to change its value in one thread, and then a new value read in another:
[C++11: 1.10/3]: The value of an object that is visible to a stream T at a certain point is the initial value of the object, the value assigned to the object, T , or the value assigned to the object by another stream , in accordance with the rules below.
However, if you do this because your object is not atomic:
[C++11: 1.10/21]: A program execution contains a data race if it contains two conflicting actions in different threads, at least one of which is not atomic, and does not happen before the other. Any such data race results in undefined behavior.
And when undefined behavior is called, anything can happen.
Bootnote
[C++11: 1.10/25]: The implementation must ensure that the last value (in the order of modification) assigned by atomic or synchronization becomes visible to all other threads over a finite period of time.
Again, note that to obtain this guarantee, the object must be atomic (for example, std::atomic<bool> ).