The "as-if" rule basically defines what transformations an implementation is allowed to perform on a legal C++ program. In short, all transformations that do not affect a program's observable behavior are allowed.
As to what exactly "observable behavior" stands for, cppreference.com seems to have a different definition with the one given by the Standard, regarding input/output. I'm not sure if that's an reinterpretation of the Standard, or a mistake.
"as-if" rule by cppreference.com:
- All input and output operations occur in the same order and with the same content as if the program was executed as written.
"as-if" rule by the Standard:
- The input and output dynamics of interactive devices shall take place in such a fashion that prompting output is actually delivered before a program waits for input. What constitutes an interactive device is implementation-defined
This difference is important to me because I want to know if a normal store reordering is a valid compiler optimization or not. Per cppreference's wording, a memory store should belong to output operations
it mentions. But according to the Standard, a memory store doesn't seem to be the output dynamics of interactive devices
. (What's interactive devices anyway?)
An example to follow.
int A = 0;
int B = 0;
void foo()
{
A = B + 1; // (1)
B = 1; // (2)
}
A modern compiler may generate the following code for function foo
:
mov 0x804a018, %eax
movl $0x1, 0x804a018 ; store 1 to B
add $0x1, %eax
mov %eax, 0x804a01c ; store 1 to A
ret
As seen, the store to A
is reordered with the store to B
. Is it compliant to the "as-if" rule? Is this kind of reordering permitted by the Standard?