Recently in an interview there was a following objective type question.
int a = 0;
cout << a++ << a;
Answers:
a. 10
Sequence points only define a partial ordering. In your case, you have (once overload resolution is done):
std::cout.operator<<( a++ ).operator<<( a );
There is a sequence point between the a++
and the first call to
std::ostream::operator<<
, and there is a sequence point between the
second a
and the second call to std::ostream::operator<<
, but there
is no sequence point between a++
and a
; the only ordering
constraints are that a++
be fully evaluated (including side effects)
before the first call to operator<<
, and that the second a
be fully
evaluated before the second call to operator<<
. (There are also
causual ordering constraints: the second call to operator<<
cannot
preced the first, since it requires the results of the first as an
argument.) §5/4 (C++03) states:
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. 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.
One of the allowable orderings of your expression is a++
, a
, first
call to operator<<
, second call to operator<<
; this modifies the
stored value of a
(a++
), and accesses it other than to determine
the new value (the second a
), the behavior is undefined.