Consider the following code:
int main()
{
int count = 0 ;
int arrInt[2] = { count++, count++ } ;
return 0 ;
}
If we compile the code using clang -std=c++03
it produces the following warning(live example):
warning: multiple unsequenced modifications to 'count' [-Wunsequenced]
int arrInt[2] = { count++, count++ } ;
^ ~~
I am not advocating for code like this but similar code came up in another question and there was disagreement over whether it is defined or not according to the standard pre-C++11. In C++11 this behavior is well defined behavior according to Are multiple mutations within initializer lists undefined behavior and indeed if I use -std=c++11
then the warning goes away.
If we look at a pre-C++11 draft standard it does not have the same language covering initializer-list so it seems we are left with Chapter 5
Expressions paragraph 4 which says:
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.57) Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.
In order for this to be undefined it would seem we would have to interpret count++, count++
as an expression and therefore each count++
as a subexpression, so is this code undefined 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:and paragraph 15 says:
then the question is whether
count++, count++
is a full expression and eachcount++
a sub-expression or is eachcount++
it's own full expression and therefore there is sequence point after each one? if we look at the grammar for this initialization from section8.5
Initializers: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 eachcount++
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):which ends up as defect report 430, which I will quote: