[comp.lang.c++] Order of evaluation bug in Stroustrup?

andrew@teslab.lab.OZ (Andrew Phillips) (11/28/90)

In "The C++ Programming Language" by Bjarne Stroustrup, on page 204,
I found the following which I believe to be a bug according to the
rules of C and C++:

  last = last->next = new ...

Since the order of evaluation of subexpressions is undefined it is
unclear whether last in last->next refers to the old value of last or
the newly assigned value of last.  Or am I missing something?


BTW I was surprised to find an even more obvious bug on the next page:

  last = (f==last) ? 0 : f->next;

which should have been:

  if (f == last) last = NULL; else last->next = f->next;

although I believe this was fixed in a later printing.


Also I was surprised to see that what is the first expression in a
for statement in C can be a statement in C++.  Presumably this was
just added for the convenience of being able to declare a variable in
the for loop, so that you can say:

  for (int i = 0; i < max; ++i) ....

But I tried several different kinds of statements in a for loop with
the C++ compiler I use and only some work.  For example this works:

  for ( {int i = 0}  ;  )  ;

but this doesn't:

  for ( for (;;) ;  ;  )  ;


Thanks in advance for any replies to these questions, especially the
first one.

Andrew.
-- 
Andrew Phillips (andrew@teslab.lab.oz.au) Phone +61 (Aust) 2 (Sydney) 289 8712

fuchs@it.uka.de (Harald Fuchs) (11/30/90)

andrew@teslab.lab.OZ (Andrew Phillips) writes:

>In "The C++ Programming Language" by Bjarne Stroustrup, on page 204,
>I found the following which I believe to be a bug according to the
>rules of C and C++:

>  last = last->next = new ...

>Since the order of evaluation of subexpressions is undefined it is
>unclear whether last in last->next refers to the old value of last or
>the newly assigned value of last.  Or am I missing something?

Yes. You are missing the fact that the assignment operator groups
right-to-left. So the execution order is:
1. eval new...
2. eval last->next
3. assign (1) to (2)
4. eval last
5. assign the result of (3) (i.e. (1)) to (4)
--

Harald Fuchs <fuchs@it.uka.de> <fuchs%it.uka.de@relay.cs.net> ...
<fuchs@telematik.informatik.uni-karlsruhe.dbp.de>   *gulp*

andrew@teslab.lab.OZ (Andrew Phillips) (12/04/90)

In article <1160@teslab.lab.OZ> andrew@teslab.lab.oz.au (I) wrote:
>I found the following which I believe to be a bug according to the
>rules of C and C++:
>
>  last = last->next = new ...

Thanks to the many people who replied that assignment operators are
right associative.  However, this does not address the question.

Right-associativity means that a=b=c is interpreted as a=(b=c) and
not (a=b)=c.  But does this mean that the compiler can't interpret it
as b=(a=c) [where I'm using brackets to show order of evaluation,
even though brackets do not do this in C/C++]?

Could someone give a reference to a standard document as to why the
above is OK.  Well do you think (I do) that this is wrong:

last->next = last = ...

since the first (right hand side :-) assignment to "last" is a side
effect, and so the compiler can use either value of "last" (the old
or the new) when evaluating "last->next"?

>  last = (f==last) ? 0 : f->next;
>
>which should have been:
>
>  if (f == last) last = NULL; else last->next = f->next;
                                        ^^^^^^ (this is important bit)

I'm sorry that I mentioned this bug as several people misunderstood
what I was saying.  You really need to look at several pages of code
in (an old version of) the book to see why it is a bug.  I now know
for a fact that this bug WAS fixed in a later printing.

>  for ( for (;;) ;  ;  )  ;

This is valid C++ syntax and I've been told does work with at least
some compilers.

Andrew.
-- 
Andrew Phillips (andrew@teslab.lab.oz.au) Phone +61 (Aust) 2 (Sydney) 289 8712

jimad@microsoft.UUCP (Jim ADCOCK) (12/11/90)

The ability to declare a variable in the for loop was left out of one
preliminary version of the C++ reference manual, with the result that
some compilers implemented during that brief time frame do not allow 
declaration of the loop variable inside the for loop.  C++ compilers 
implemented before and after that time period do support declaration of
the loop variable inside the for statement.  Such use is
common within the C++ community, and supported by the current
working papers of the ANSI-C++ committee.