As the title says,
An typical answer one would get is:
The rule that allows any and all code transformations that do not change the observable behavior of the program
From time to time we keep getting behaviors from certain implementations which are attributed to this rule. Many a times wrongly. So, What exactly is this rule. The standard does not clearly mention this rule as a section or paragraph, so what exactly falls under the purview of this rule? To me it seems like a grey area which is not defined in detail by the standard. Can someone elaborate on the details citing the references from the standard.
Note: Tagging this as C and C++ both, because it is relevant to both languages.
In C11 the rule is never called by that name. However C, just like C++, defines the behaviour in terms of abstract machine. The as-if rule is in C11 5.1.2.3p4 and p6:
What is the "as-if" rule?
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" (see below for a precise definition) are allowed.
The goal is to give implementations freedom to perform optimizations as long as the behavior of the program remains compliant with the semantics specified by the C++ Standard in terms of an abstract machine.
Where does the Standard introduce this rule?
The C++11 Standard introduces the "as-if" rule in Paragraph 1.9/1:
Also, an explanatory footnote adds:
What does the rule mandate exactly?
Paragraph 1.9/5 further specifies:
It is worth stressing that this constraint applies when "executing a well-formed program" only, and that the possible outcomes of executing a program which contains undefined behavior are unconstrained. This is made explicit in Paragraph 1.9/4 as well:
Finally, concerning the definition of "observable behavior", Paragraph 1.9/8 goes as follows:
Are there situations where this rule does not apply?
To the best of my knowledge, the only exception to the "as-if" rule is copy/move elision, which is allowed even though the copy constructor, move constructor, or destructor of a class have side effects. The exact conditions for this are specified in Paragraph 12.8/31: