Re: sequence points
On Oct 15, 2:43 am, Lance Diduck <lancedid...@nyc.rr.com> wrote:
> On Oct 14, 4:47 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> > Please consider
> > #include <iostream>
> > int main ( void ) {
> > int a = 0;
> > a = ( (a = 5), 4 ); // (*)
> > std::cout << a << '\n';
> > }
> > I would like to determine whether line(*) has undefined
> > behavior (modifying a variable twice between sequence
> > points).
> > What I think is this: We have an assignment expression
> > lhs = rhs
> > where the right hand side is this:
> > (a = 5), 4
> > I note that the comma will introduce a sequence point that
> > separates the side-effects of a=5 from the side-effects of
> > 4. The main question therefore is whether the right hand
> > side
> > (a = 5), 4
> > can have a value before the side effects of its evaluation
> > take place. My understanding of the standard is that
> > sequence points only separate side effect but do not tell us
> > anything about how, where and when values of expressions are
> > established. However, if that understanding is correct, the
> > abstract machine would be allowed to predict that the right
> > hand side will have value 4 and perform the side effect of
> > the ambient assignment
> > lhs = rhs
> > before the side effects of the rhs take place. Along this
> > possible path of execution, the value of a would be modified
> > twice. Thus, as of now, I believe that line (*) has
> > undefined behavior.
> > However, I am not sure about this interpretation of the
> > standard; and I would appreciate your . (In fact, I hope
> > that I am wrong.)
> > Note that similar considerations would apply to:
> > a = f();
> > Is it guaranteed that the side-effects of evaluating f()
> > take place before the value of a is changed? or would a
> > conforming implementation allowed to put all side-effects of
> > f() on hold until it knows the value, perform the
> > assignment, and then run the side-effects of f()?
> I would believe that an good optimising compiler would recognize that
> int a=0;
> a=((a=5),4);
> cout<<a;
> would reduce to
> cout<<4;
> since assigning (non volatile)int has no side effects. Whether
> this is correct by the standard (the C standard at that) there
> is probably no consensus.
That's definitly allowed, under the "as if" rule, even if the
expression in question has no undefined behavior, but that's a
separate issue.
The issue with sequence points is more complex. As Kai-Uwe
correctly understands, they only introduce a partial ordering.
I *think* that in this case, the two assignments are ordered,
because the outer assignment requires the results of the rhs,
and there is a sequence point in the expression there. But I'd
ask the question in comp.std.c/comp.std.c++, just to be sure.
Note that in C++, the current draft replaces sequence points
with another concept, in order to be able to define ordering
when threads are involved, so the answer may change in the next
version of the standard.
> This is like the "is the Return Value Optimization Correct"
> debate? RVO is usually correct,but not always, esp if the copy
> constructor has a side effect. But in practice, people want RVO
> anyway.
RVO is always correct, even if the copy constructor has a side
effect, because the standard says it is.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|