Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

order of evaluation

4 views
Skip to first unread message

Andrea Murru

unread,
Jul 26, 2003, 7:08:17 AM7/26/03
to
A simple question for some c++ guru:

in this line of code

i = 1;
s[i] = s[--i];

what can I tell about order of evaluation?

C++ Builder 6.0 and Visual C++ 7.1 assign s[0] to s[0], while gcc 3.2
and assigns s[1] to s[0].

How is wrong?

Thanks in advance.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Bo Persson

unread,
Jul 27, 2003, 6:33:26 AM7/27/03
to

"Andrea Murru" <andre...@tiscalinet.it> skrev i meddelandet
news:5950242b.03072...@posting.google.com...

> A simple question for some c++ guru:
>
> in this line of code
>
> i = 1;
> s[i] = s[--i];
>
> what can I tell about order of evaluation?

Nothing much. The assignment ought to be last (if it had been a proper
expression).

>
> C++ Builder 6.0 and Visual C++ 7.1 assign s[0] to s[0], while gcc
3.2
> and assigns s[1] to s[0].
>
> How is wrong?

You are wrong! :-)

If you update an object in an expression, you cannot also use that
object for something else (except for reading its initial value,
obviously).

As you both use and update "i" in your expression, you have broken the
contract with the compiler and it is free to do anything. Not limited
to the two behaviours you have seen.


Bo Persson
bo...@telia.com

Thomas Mang

unread,
Jul 27, 2003, 6:45:15 AM7/27/03
to

Andrea Murru schrieb:

> A simple question for some c++ guru:
>
> in this line of code
>
> i = 1;
> s[i] = s[--i];
>
> what can I tell about order of evaluation?
>
> C++ Builder 6.0 and Visual C++ 7.1 assign s[0] to s[0], while gcc 3.2
> and assigns s[1] to s[0].
>
> How is wrong?

All three are correct.

It's undefined behavior, so simply avoid such expressions.


regards,

Thomas

Dhruv

unread,
Jul 27, 2003, 6:48:08 AM7/27/03
to
On Sat, 26 Jul 2003 07:08:17 -0400, Andrea Murru wrote:

> A simple question for some c++ guru:
>
> in this line of code
>
> i = 1;
> s[i] = s[--i];
>
> what can I tell about order of evaluation?
>
> C++ Builder 6.0 and Visual C++ 7.1 assign s[0] to s[0], while gcc 3.2
> and assigns s[1] to s[0].
>

Both are correct (or wrong)!!!

Even I found this out a few days ago (Thanks to all who helped me
there!!!!!!).

Chp. 5:
4. 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 previ-
ous and next sequence point a scalar object shall have its stored
value modified at most once by the evaluation of an expression. Fur-
thermore, 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 expres-
sion; otherwise the behavior is undefined.

> i = 1;
> s[i] = s[--i];

So, in this case, the behaviour is undefined, because the value i is being
read once to increment it, and then again on the lhas of the = sign, so
this double read is the one that's causing the problem.

The second part menas that even this is invalid:

int b = (s[i] = s[--i]);

Assuming that s is an array of ints.

Or, to be more general,

typeof(s[0]) b = (s[i] = s[--i]);


Regards,
-Dhruv.

Sebastian Moleski

unread,
Jul 27, 2003, 6:54:22 AM7/27/03
to

"Andrea Murru" <andre...@tiscalinet.it> wrote in message
news:5950242b.03072...@posting.google.com...

> A simple question for some c++ guru:
>
> in this line of code
>
> i = 1;
> s[i] = s[--i];
>
> what can I tell about order of evaluation?

It's undefined behavior. There is no guarantee that the left or the right side
of the assignment are evaluated first.

sm

Francis Glassborow

unread,
Jul 27, 2003, 12:01:33 PM7/27/03
to
In message <5950242b.03072...@posting.google.com>, Andrea
Murru <andre...@tiscalinet.it> writes

>A simple question for some c++ guru:
>
>in this line of code
>
>i = 1;
>s[i] = s[--i];
>
>what can I tell about order of evaluation?
--i must be evaluated before the right hand call of subscript on s the
operands of operator = must both be evaluated before it is
evaluated.

Your code has undefined behaviour because it breaches an explicit
requirement of the Standard.

i is used twice in your assignment expression statement without an
intervening sequence point. One of those uses modifies i. That is always

undefined behaviour and the resulting code can do anything it likes.

--
ACCU Spring Conference 2003 April 2-5
The Conference you should not have missed
ACCU Spring Conference 2004 Late April
Francis Glassborow ACCU

Heinz Ozwirk

unread,
Jul 27, 2003, 1:00:51 PM7/27/03
to
"Andrea Murru" <andre...@tiscalinet.it> schrieb im Newsbeitrag
news:5950242b.03072...@posting.google.com...
: A simple question for some c++ guru:

:
: in this line of code
:
: i = 1;
: s[i] = s[--i];
:
: what can I tell about order of evaluation?

a) 1 is assigned to i first.
b) i is decremented before the right side of the second statement is
evaluated.

: C++ Builder 6.0 and Visual C++ 7.1 assign s[0] to s[0], while gcc 3.2


: and assigns s[1] to s[0].
:
: How is wrong?

None of those above. The standard does not define an order of valuation.

Heinz

Jack Klein

unread,
Jul 27, 2003, 1:01:27 PM7/27/03
to
On 26 Jul 2003 07:08:17 -0400, andre...@tiscalinet.it (Andrea
Murru) wrote in comp.lang.c++.moderated:

> A simple question for some c++ guru:
>
> in this line of code
>
> i = 1;
> s[i] = s[--i];

The code has undefined behavior.

> what can I tell about order of evaluation?
>
> C++ Builder 6.0 and Visual C++ 7.1 assign s[0] to s[0], while gcc 3.2
> and assigns s[1] to s[0].
>
> How is wrong?

The code is wrong. Each compiler is just as correct or incorrect as any
of the others. The code produces undefined behavior and therefore the
C++ standard literally places no requirements at all on what happens.

> Thanks in advance.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

Ed Avis

unread,
Jul 27, 2003, 7:50:18 PM7/27/03
to
"Bo Persson" <bo...@telia.com> writes:

>>s[i] = s[--i];

>As you both use and update "i" in your expression, you have broken


>the contract with the compiler and it is free to do anything. Not
>limited to the two behaviours you have seen.

Are you sure about this? Another poster quoted:

>Chp. 5:
>
>4. 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.

This seems to imply that the compiler can choose any ordering it likes
among the subexpressions, but it can't do the Towers of Hanoi.

--
Ed Avis <e...@membled.com>

Andrew Koenig

unread,
Jul 28, 2003, 5:50:00 AM7/28/03
to
>> 4. 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.

Ed> This seems to imply that the compiler can choose any ordering it likes
Ed> among the subexpressions, but it can't do the Towers of Hanoi.

This paragraph says (among other things) that if a scalar object is
fectched and stored between two consecutive sequence points, and the
fetch is for a purpose other than determining the value to store,
then the behavior is undefined.

In

s[i] = s[--i];

the value of i is fetched as part of the left-hand side stored as part
of the right-hand side. The fetch is as part of evaluating s[i], rather
than as part of determining a value to store in i. There are no sequence
points embedded in this expression.

Therefore, the behavior is undefined.

--
Andrew Koenig, a...@acm.org

llewelly

unread,
Jul 28, 2003, 5:54:16 AM7/28/03
to
Ed Avis <e...@membled.com> writes:

> "Bo Persson" <bo...@telia.com> writes:
>
>>>s[i] = s[--i];
>
>>As you both use and update "i" in your expression, you have broken
>>the contract with the compiler and it is free to do anything. Not
>>limited to the two behaviours you have seen.
>
> Are you sure about this? Another poster quoted:
>
>>Chp. 5:
>>
>>4. 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.
>
> This seems to imply that the compiler can choose any ordering it likes
> among the subexpressions, but it can't do the Towers of Hanoi.

Reading the part I underlined, I came to the following line of
thought:

in '--i', i is a scalar object having its stored value modified at
most once.

in 's[i]' i is being accessed, but *not* to determine the value
stored.

Since the order of evaluation of operators is unspecified, the 'i'
in 's[i]' may be evaluated before the '--i' in 's[--i]'. This
would result in an access of the prior value of i.

Since at least one ordering of the subexpressions of the full
expression fails to meet the requirements, we have undefined
behavior.

I'm not certain the above line of reasoning is correct, but I think
I'll count on it until I see a sound objection.

James Dennett

unread,
Jul 28, 2003, 5:57:14 AM7/28/03
to
Ed Avis wrote:
> "Bo Persson" <bo...@telia.com> writes:
>
>
>>>s[i] = s[--i];
>
>
>>As you both use and update "i" in your expression, you have broken
>>the contract with the compiler and it is free to do anything. Not
>>limited to the two behaviours you have seen.
>
>
> Are you sure about this? Another poster quoted:
>
>
>>Chp. 5:
>>
>>4. 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.
>
>
> This seems to imply that the compiler can choose any ordering it likes
> among the subexpressions, but it can't do the Towers of Hanoi.
>

Actually, the paragraph you quote gives the implementation
the freedom to do the Towers of Hanoi. That's what the
"the requirements of this paragraph shell be met... ; otherwise
the behavior is undefined" says, speaking of requirements placed
on user code. If you write code such that reads and writes
between sequence points break the rules, all bets are off.

This has been covered many times in the past; the archives of
comp.std.c++ will provide many repetitions, as will those of
any other major C++ newsgroup I know of.

-- James.

Hyman Rosen

unread,
Jul 28, 2003, 5:44:18 PM7/28/03
to
llewelly wrote:
> I'm not certain the above line of reasoning is correct, but I think
> I'll count on it until I see a sound objection.

How many more millions of times are we going to have to have
this same stupid thread? Why don't we just define the evaluation
order (just like Java) so that we can finally tell people that
their code is legal and exactly what it does? Does C++ really
need the grief, aggravation, and bugs that undefined order
causes?

The Java rules are exquisitely simple -
function arguments are evaluated left to right
operands of an operator are evaluated left to right
lvalue "addresses" are evaluated just like rvalues

For the case in question, 's[i] = s[--i];' this would be
1) evaluate s[i], and capture its "address" since
it's an lvalue
2) decrement i
3) evaluate s[decremented-i] as an rvalue
4) assign this rvalue to the saved lvalue

In other words, the same as writing
s[i] = s[i - 1];
--i;

Ed Avis

unread,
Jul 28, 2003, 5:44:59 PM7/28/03
to
Thanks for the explanation, I misinterpreted 'The requirements of this
paragraph shall be met for each allowable ordering...'. I thought it
was some kind of restriction on the compiler, but in fact it is a
restriction on user code. If you write code where any one allowable
ordering doesn't meet the paragraph's requirements, then the behaviour
is undefined.

--
Ed Avis <e...@membled.com>

ka...@gabi-soft.fr

unread,
Jul 28, 2003, 5:51:28 PM7/28/03
to
Ed Avis <e...@membled.com> wrote in message
news:<l165lny...@budvar.future-i.net>...
> "Bo Persson" <bo...@telia.com> writes:

> >>s[i] = s[--i];

> >As you both use and update "i" in your expression, you have broken
> >the contract with the compiler and it is free to do anything. Not
> >limited to the two behaviours you have seen.

> Are you sure about this? Another poster quoted:

> >Chp. 5:

> >4. 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.

> This seems to imply that the compiler can choose any ordering it likes
> among the subexpressions, but it can't do the Towers of Hanoi.

There are two separate issues. A compiler is free to evaluate the
expressions in any order it pleases (modulo a few special cases not
relevant here). If, however, in any legal ordering, you modify an
object, and access it elsewhere other than for the purpose of
determining the new value, you code has undefined behavior. This code
comes under the second case; it is undefined behavior.

--
James Kanze GABI Software mailto:ka...@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

ka...@gabi-soft.fr

unread,
Jul 29, 2003, 6:18:48 PM7/29/03
to
Hyman Rosen <hyr...@mail.com> wrote in message
news:<10594005...@master.nyc.kbcfp.com>...

> llewelly wrote:
> > I'm not certain the above line of reasoning is correct, but I think
> > I'll count on it until I see a sound objection.

> How many more millions of times are we going to have to have this same
> stupid thread? Why don't we just define the evaluation order (just
> like Java) so that we can finally tell people that their code is legal
> and exactly what it does? Does C++ really need the grief, aggravation,
> and bugs that undefined order causes?

Yes. The rule has several important advantages:

- It generates considerable traffic in the newsgroups. I mean, what
would we discuss here if we didn't have such issues? And of course,
the more traffic in the newsgroups, the more the language seems
important.

- It always us experts to show off, by showing that we understand such
subtlies. Also, subtle difficulties in the language, which cause
problems for the beginner, make the language seem harder than it
really is, which in turn means that consultants in the language can
ask for (and get) higher rates.

Those are about the only real reasons I can think of, but you'll have to
admit that the last one is absolutely conclusive.

--
James Kanze GABI Software mailto:ka...@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

0 new messages