------- Comment #14 from igodard at pacbell dot net 2010-08-31 02:20 -------
Reopened, based on following communication from Clark Nelson
> > In one interpretation, it means the rvalue evaluation of b and f(); in
> > this interpretation the ordering of the operand evaluations is undefined
> > and hence the value of b at and after the assignment is also undefined.
> > It is unclear how the assignment receives an lvalue to assign to in this
> > interpretation.
I don't see how this interpretation is viable. As you point out, if you
evaluate the LHS as an rvalue, there's no way to do the assignment.
> > In the second interpretation, it means the lvalue evaluation of b and the
> > rvalue evaluation of f(); in this interpretation the lvalue-to-rvalue
> > conversion of b takes place within the assignment, so consequently f()
> > must be evaluated before the conversion takes place. Hence, the assignment
> > receives the (lvalue) b with a well-defined rvalue of true, and the value
> > after the assignment is also well-defined and true.
I agree with this. (Except the part where you describe lvalue-to-rvalue
conversion of b happening within the assignment. That conversion doesn't
actually happen at all. Not that that matters to the conclusion.)
I looked at the discussion in the bug. The issue has nothing to do with whether
the evaluation of |= acts like a function call (which of course it doesn't).
Instead, it has to do with whether the evaluation of |= is allowed to overlap
with the execution of f.
Even before the turn of the century, function calls were described as having
sequence points at their beginning and end, and that was always intended to be
interpreted as disallowing overlapping execution between caller and callee.
But under the new formulation, the non-overlapping requirement is stated even
more clearly. In C++, see 5.17p1:
With respect to an indeterminately-sequenced function call, the operation of a
compound assignment is a single evaluation.
In other words, it is not allowed to implement |= by fetching b, then calling
f, evaluating the result of |, and storing that result. The evaluation of |=
has to happen either entirely before or entirely after the execution of the
called function, and in this case it clearly can't happen before. So this code
has perfectly well-defined behavior, and it's what Ivan expects.
Now, all that being said, the "new rules" were intended primarily just to be a
clearer formulation of what the old rules always were. It could be argued that
this is just a "substantive clarification" of the old rules. But, for example,
I didn't put it in of my own initiative; I was specifically asked to make
things work this way.
igodard at pacbell dot net changed:
What |Removed |Added