Ron Natalie said:
The compiler is free to reorder the expression. If you want to enforce ordering
you have to introduce sequence points in the calculation.
There are two places in the Standard that might be considered relevant:
1) 1.9 para 15 (which is a note and so non-normative but can give a clue
as to intent)
There it requires that the operators are really associative and
commutative -- and a non-normative footnote to the non-normative note
adds that this is never considered to be the case for overloaded
operators)
It then proceeds to give source code examples re int values and fails to
give any guidance in the case of floating point.
When I combine the above with C's rules (which explicitly forbid
re-ordering) I come to the conclusion that fp arithmetic operators are
not 'really' associative and commutative and so the limited licence to
regroup (note not re-order) does not apply. But even if it did the best
that could be achieved with the above is:
double d = 1.1 + x + (2.2 + 3.3);
which the compiler could transform to :
double d = 1.1 + x + 5.5;
Had the writers of that section meant re-order they could have said so.
2) Section 5 para 4 is actually no more helpful. Historically this
formulation has not been taken as a licence for re-ordering successive
applications of the same operator other than where explicit licence is
granted (or can be deduced fro the as-if rule) if op is a left-to-right
associative operator:
a op b op c;
must be evaluated as:
(a op b) op c;
and not as:
a op (b op c);
However:
a op1 b op2 c op1 d;
with op1 having a higher precedence than op2 allows for (a op1 b) and (c
op1 d) to be evaluated in either order. That has been the normal
interpretation of the rule with regard to order of evaluation of
sub-expressions.
It is probably safer with modern high optimisation implementations to
write code with sequence points enforcing intent but I can see nothing
in the C++ Standard that allows C++ to treat floating point expressions
differently to the way that a C compiler is required to.