Are multiple mutations of the same variable within initializer lists undefined behavior pre C++11

The code is not undefined pre-C++11 but the evaluation order is unspecified. If we look at the draft standard section 1.9 Program execution paragraph 12 says:

A full-expression is an expression that is not a subexpression of another expression. […]

and paragraph 15 says:

There is a sequence point at the completion of evaluation of each full-expression12).

then the question is whether count++, count++ is a full expression and each count++ a sub-expression or is each count++ it’s own full expression and therefore there is sequence point after each one? if we look at the grammar for this initialization from section 8.5 Initializers:

initializer-clause:
  assignment-expression
  { initializer-list ,opt }
  { }
initializer-list:
  initializer-clause
  initializer-list , initializer-clause

the only expression we have is an assignment-expression and the , separating the components is part of the initializer-list and and not part of an expression and therefore each count++ is a full expression and there is a sequence point after each one.

This interpretation is confirmed by the following gcc bug report, which has very similar code to mine(I came up with my example way before I found this bug report):

int count = 23;
int foo[] = { count++, count++, count++ };

which ends up as defect report 430, which I will quote:

[…]I believe the standard is clear that each initializer expression in the above is a full-expression (1.9 [intro.execution]/12-13; see also issue 392) and therefore there is a sequence point after each expression (1.9 [intro.execution]/16). I agree that the standard does not seem to dictate the order in which the expressions are evaluated, and perhaps it should. Does anyone know of a compiler that would not evaluate the expressions left to right?

Leave a Comment