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

THE POSTINCREMENT TIME

40 views
Skip to first unread message

Vladimir Zolotykh

unread,
Apr 16, 2003, 12:08:52 PM4/16/03
to
Hi

Could someone explain why

int i = 1;
cout << i++ << i;

outputs 11 but

int i = 1;
cout << i << i++;

does 21 ? Should not it be 11 in both cases? What is the general rule
for the time of side effect of postincrement ++ operators ? I vaguely
remember something like that 'in _this_ statement the old value should
be used. The increment must be done before the beginning of the nex
statement;' Is this true ? Could you please throw some light on this
point ?

Thanks in advance

--
Vladimir Zolotykh


[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

Hyman Rosen

unread,
Apr 17, 2003, 5:30:54 AM4/17/03
to
Vladimir Zolotykh wrote:
> Could someone explain why
> int i = 1;
> cout << i++ << i;
> outputs 11 but
> int i = 1;
> cout << i << i++;
> does 21 ? Should not it be 11 in both cases? What is the general rule
> for the time of side effect of postincrement ++ operators ?

OK, so let's all jump in yet again and explain all about sequence
points, and why this code causes nasal demons. Wouldn't it be nice
if we could just say that things execute left-to-right, so that the
first example prints 12 and the second 11?

Jack Klein

unread,
Apr 17, 2003, 5:48:03 AM4/17/03
to
On 16 Apr 2003 12:08:52 -0400, Vladimir Zolotykh
<gsm...@eurocom.od.ua> wrote in comp.lang.c++.moderated:

> Hi
>
> Could someone explain why
>
> int i = 1;
> cout << i++ << i;
>
> outputs 11 but
>
> int i = 1;
> cout << i << i++;
>
> does 21 ? Should not it be 11 in both cases? What is the general rule
> for the time of side effect of postincrement ++ operators ? I vaguely
> remember something like that 'in _this_ statement the old value should
> be used. The increment must be done before the beginning of the nex
> statement;' Is this true ? Could you please throw some light on this
> point ?
>
> Thanks in advance

There is no sequence point in the expression that you typed, which is
the term you are looking for. There is only one statement, not more
than one.

There are two function calls, to cout.operator<<(), but the compiler
is free to evaluate the cout object and the two expressions containing
i in any order before performing those function calls.

See http://www.eskimo.com/~scs/C-faq/q3.2.html in the C language FAQ.
There are similar examples in the FAQ for comp.lang.c++ (link in my
signature), but I had the comp.lang.c FAQ link handy and the issue is
basically the same in both languages. C++ inherits its notions of
sequence points and undefined behavior in this regard pretty much
intact from C.

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

Matthias Hofmann

unread,
Apr 19, 2003, 5:46:45 AM4/19/03
to
> See http://www.eskimo.com/~scs/C-faq/q3.2.html in the C language FAQ.
> There are similar examples in the FAQ for comp.lang.c++ (link in my
> signature), but I had the comp.lang.c FAQ link handy and the issue is
> basically the same in both languages. C++ inherits its notions of
> sequence points and undefined behavior in this regard pretty much
> intact from C.

I have checked out this link and it made many things clear to me. But there
is still one thing I don't understand: Is code like

cout << i << i++;

considered to be "undefined" or just "unspecified"? As I have just learned,
this is a crucial distinction, see
http://www.eskimo.com/~scs/C-faq/q11.33.html

Terje Slettebø

unread,
Apr 19, 2003, 5:47:08 AM4/19/03
to
Jack Klein <jack...@spamcop.net> wrote in message news:<k92s9vkhgsi1leda5...@4ax.com>...

As Hyman Rosen said, this issue has been covered before. However, I
think there needs to be a correction to this reply, since there's no
undefined behaviour in this case, only unspecified.

The example code is different in C++ and C, since it involves
user-defined operators (operator<<).

It's correct that if this was C code, it would have had undefined
behaviour, since in that case, it reads more than once from the
variable, and there's a write to it, between sequence points.

However, as this is C++ code, with user-defined operators, there are
several sequence points (at least two per function call), so there's
no undefined behaviour.

The order of evaluation of an expression is unspecified, which means
that for the example program, you may get different output on
different compilers, or the same compiler in different situations.

Thus, the issue (in C++) is not sequence points, but order of
evaluation of an expression, which is the same as in C.


Regards,

Terje

tslettebo at chello no

Matthias Hofmann

unread,
Apr 19, 2003, 5:52:20 AM4/19/03
to
This link might interest you. It explainsthe implications of sequence
points, prevedence and order of evaluation very well:

http://www.eskimo.com/~scs/readings/precvsooe.960725.html

Matthias Hofmann

unread,
Apr 19, 2003, 5:08:52 PM4/19/03
to
Terje Slettebř <terjes.@chello.no> schrieb in im Newsbeitrag:
9e3a34f7.03041...@posting.google.com...

> Jack Klein <jack...@spamcop.net> wrote in message
news:<k92s9vkhgsi1leda5...@4ax.com>...
> > On 16 Apr 2003 12:08:52 -0400, Vladimir Zolotykh
> > <gsm...@eurocom.od.ua> wrote in comp.lang.c++.moderated:
> However, as this is C++ code, with user-defined operators, there are
> several sequence points (at least two per function call), so there's
> no undefined behaviour.

How come there are at least two sequence points per function call? I thought
there was exactly one sequence point just prior to entering a function?

And another question: Does the following code yield undefined behaviour,
then?

Func( ++i, i );

In this case, i is read from twice and also modified and I can see no
sequence point separating the reads.

John Potter

unread,
Apr 20, 2003, 6:28:54 AM4/20/03
to
On 19 Apr 2003 05:46:45 -0400, "Matthias Hofmann" <hof...@anvil-soft.com>
wrote:

> I have checked out this link and it made many things clear to me. But there
> is still one thing I don't understand: Is code like

> cout << i << i++;

> considered to be "undefined" or just "unspecified"?

It is undecidable. :)

It is unspecified which of the expressions will be evaluated first and they
may even be evaluated in parallel. Left to right is a valid order and the
rvalue conversion uses the old value of i for purposes other than to
determine the new value and has no sequence point between that and the
modification of i. If any order has undefined behavior, the expression has
undefined behavior.

On the practical side, I have never seen anything other than X X or X+1 X
which would be nicely unspecified. Since you still do not know what will
happen, just say NO to writing that crap.

John

John Potter

unread,
Apr 20, 2003, 6:29:31 AM4/20/03
to
On 19 Apr 2003 05:47:08 -0400, terjes.@chello.no (Terje Sletteb) wrote:

> However, as this is C++ code, with user-defined operators, there are
> several sequence points (at least two per function call), so there's
> no undefined behaviour.

You are only adding confusion.

cout << i << i++

op<<(op<<(cout, i), i++)

evaluate i++
evaluate i
evaluate cout
call first/inner<<
call second/outer<<

There are zero sequence points between the two uses of i and i is modified.
The first three things could be evaluated in any order including in
parallel. If any valid evaluation order has undefined behavior, the
statement has undefined behavior.

It is undefinded behavior.

John

John Potter

unread,
Apr 20, 2003, 6:41:43 AM4/20/03
to
On 19 Apr 2003 17:08:52 -0400, "Matthias Hofmann" <hof...@anvil-soft.com>
wrote:

> How come there are at least two sequence points per function call? I thought


> there was exactly one sequence point just prior to entering a function?

Because this is C++. One after evaluating parameters before executing
anything in the called function. One after copying the return value before
executing anything in the calling function. C only needs one.

> And another question: Does the following code yield undefined behaviour,
> then?

Yes.

> Func( ++i, i );

> In this case, i is read from twice and also modified and I can see no
> sequence point separating the reads.

You are right. That is just as undefined as the other one. Those function
call sequence points made no difference because all of the arguments may
be evaluated without any sequence points prior to any call.

John

Hyman Rosen

unread,
Apr 20, 2003, 6:45:27 AM4/20/03
to
Terje Sletteb wrote:
> As Hyman Rosen said, this issue has been covered before.
>
> The example code is different in C++ and C, since it involves
> user-defined operators (operator<<).

As I said, we've been suffering from these idiotic gotchas for
decades now, and even people who think they know the answers,
like you, are wrong. The OP's code looks like
cout.op<<(i++).op<<(i);
and
cout.op<<(i).op<<(i++);
The compiler is free to evaluate *all* the arguments before any
function is called. Therefore, these expressions both run afoul
of 5.4 "the prior value shall be accessed only to determine the
value to be stored" and result in undefined behavior.

Francis Glassborow

unread,
Apr 20, 2003, 3:29:42 PM4/20/03
to
In message <9e3a34f7.03041...@posting.google.com>, Terje
Slettebř <"terjes."@chello.no.invalid> writes

>However, as this is C++ code, with user-defined operators, there are
>several sequence points (at least two per function call), so there's no

>undefined behaviour.

True, but no help for situations such as:

x = foo(i) + bar(i++);

because the sequence points (after the evaluation of the arguments and
at the point of return -- even if the standard never mentioned this
second one unless the body of the function lacks any full expressions)
are too late to protect the evaluation of the two arguments which may
happen without any intervening sequence points. So, unless i is an
object of a UDT, with an operator++() defined, such expressions can
exhibit undefined behaviour.


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

Kevlin Henney

unread,
Apr 21, 2003, 9:09:26 AM4/21/03
to
In article <iac3av0qoueq25cvc...@4ax.com>, John Potter
<jpo...@falcon.lhup.edu> writes

>On 19 Apr 2003 05:47:08 -0400, terjes.@chello.no (Terje Sletteb) wrote:
>
> > However, as this is C++ code, with user-defined operators, there are
> > several sequence points (at least two per function call), so there's
> > no undefined behaviour.
>
>You are only adding confusion.
>
> cout << i << i++
>
> op<<(op<<(cout, i), i++)
>
> evaluate i++
> evaluate i
> evaluate cout
> call first/inner<<
> call second/outer<<
>
>There are zero sequence points between the two uses of i and i is modified.
>The first three things could be evaluated in any order including in
>parallel. If any valid evaluation order has undefined behavior, the
>statement has undefined behavior.

The only reasonable possibilities for undefined behaviour are if i++
would cause integer overflow or if any of the objects involved have been
corrupted. If that were to occur the whole expression would indeed have
undefined behaviour. In other cases the example simply has unspecified
behaviour.

As for parallel execution, if that option were to give anything other
than unspecified behaviour it would not conform to the standard.

>It is undefinded behavior.

In clause 5 the standard specifies the example of interest as having
unspecified behaviour. Any other interpretation is undefined ;->

Kevlin
____________________________________________________________

Kevlin Henney phone: +44 117 942 2990
mailto:kev...@curbralan.com mobile: +44 7801 073 508
http://www.curbralan.com fax: +44 870 052 2289
Curbralan: Consultancy + Training + Development + Review
____________________________________________________________

Hyman Rosen

unread,
Apr 21, 2003, 2:29:13 PM4/21/03
to
Kevlin Henney wrote:
> The only reasonable possibilities for undefined behaviour are...

No. The example has undefined behavior because the Standard says
that it has undefined behavior. The only way to portably make this
example have defined behavior is to change the standard.

Francis Glassborow

unread,
Apr 21, 2003, 2:33:50 PM4/21/03
to
In message <H9$lqBBvS...@curbralan.com>, Kevlin Henney
<kev...@curbralan.com> writes

>In article <iac3av0qoueq25cvc...@4ax.com>, John Potter
><jpo...@falcon.lhup.edu> writes
> >On 19 Apr 2003 05:47:08 -0400, terjes.@chello.no (Terje Sletteb) wrote:
> >
> > > However, as this is C++ code, with user-defined operators, there are
> > > several sequence points (at least two per function call), so there's
> > > no undefined behaviour.
> >
> >You are only adding confusion.
> >
> > cout << i << i++
> >
> > op<<(op<<(cout, i), i++)
> >
> > evaluate i++
> > evaluate i
> > evaluate cout
> > call first/inner<<
> > call second/outer<<
> >
> >There are zero sequence points between the two uses of i and i is modified.
> >The first three things could be evaluated in any order including in
> >parallel. If any valid evaluation order has undefined behavior, the
> >statement has undefined behavior.
>
>The only reasonable possibilities for undefined behaviour are if i++
>would cause integer overflow or if any of the objects involved have been
>corrupted. If that were to occur the whole expression would indeed have
>undefined behaviour. In other cases the example simply has unspecified
>behaviour.

You surprise me. I always believed that the point of sequence points is
that they are stable islands in regard to side effects. Between them
there is no guarantee about when and how they take place. While two
evaluations are supposed to take place as if sequentially there is no
requirement about their side effects. Unless writing to an int is an
atomic operation it is theoretically possible that the program tries to
access i for reading whilst the storage is being updated. Note I say
theoretically, I know that it would be incredible if it happened in
practice but I believe that there is no requirement that the system
schedule reads and writes sequentially.


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

John Potter

unread,
Apr 22, 2003, 6:28:44 AM4/22/03
to
On 21 Apr 2003 09:09:26 -0400, Kevlin Henney <kev...@curbralan.com> wrote:

> In article <iac3av0qoueq25cvc...@4ax.com>, John Potter
> <jpo...@falcon.lhup.edu> writes

> > cout << i << i++

> >It is undefinded behavior.

> In clause 5 the standard specifies the example of interest as having
> unspecified behaviour. Any other interpretation is undefined ;->

I assume that you are refering to 5/4 where the normative text states
that it is undefined and the non-normative examples incorrectly label
this as unspecified. See core issue 351.

John

Terje Slettebø

unread,
Apr 22, 2003, 6:53:21 AM4/22/03
to
Francis Glassborow <francis.g...@ntlworld.com> wrote in message news:<O4Z2KkCl...@robinton.demon.co.uk>... > Sletteb <"terjes."@chello.no.invalid> writes

> >However, as this is C++ code, with user-defined operators, there are
> >several sequence points (at least two per function call), so there's no
>
> >undefined behaviour.
>
> True, but no help for situations such as:
>
> x = foo(i) + bar(i++);
>
> because the sequence points (after the evaluation of the arguments and
> at the point of return -- even if the standard never mentioned this
> second one unless the body of the function lacks any full expressions)
> are too late to protect the evaluation of the two arguments which may
> happen without any intervening sequence points. So, unless i is an
> object of a UDT, with an operator++() defined, such expressions can
> exhibit undefined behaviour.

I'm not sure if I understand the difference between this example, and
the one at the start of this thread.

If we rewrite them, we get (using non-member functions for clarity,
and it shouldn't change the outcome, and likewise with assuming "+" is
a user-defined operator):

f(g(c),c++) // operator<<(operator<<(cout,c),c++)

f(g(c),h(c++)) // operator+(foo(i),bar(i++))

IIUC, you (and Kevlin Henney) say that the first doesn't have
undefined, but unspecified behaviour, like I've said, but that new
example here may have it.

If either of them were to have undefined behaviour - due to 5.4 "the


prior value shall be accessed only to determine the value to be

stored", as Hyman Rosen quoted, it would mean that it can evaluate "c"
and "c++", without an intervening sequence point.

In what way are the above two expressions different, leading to this
different outcome?


Regards,

Terje

Kevlin Henney

unread,
Apr 22, 2003, 7:00:44 AM4/22/03
to
In article <10509339...@master.nyc.kbcfp.com>, Hyman Rosen
<hyr...@mail.com> writes

>Kevlin Henney wrote:
>> The only reasonable possibilities for undefined behaviour are...
>
>No. The example has undefined behavior because the Standard says
>that it has undefined behavior. The only way to portably make this
>example have defined behavior is to change the standard.

My reading of the text of [5/4] may in that case be a little fuzzy. I
guess the critical sentence is "Furthermore, the prior value shall be
accessed only to determine the value to be stored." When I take a strong
interpretation of the whole paragraph that suggests that one of the
examples,

i = ++i + 1; // the behavior is unspecified

should say "undefined", and when I take a weaker reading of the
paragraph it suggests that the example under discussion (assuming that I
have the right one) is "unspecified" rather than "undefined". Comments?

{I think this would have been better posted to comp.std.c++. -mod/fwg}

Kevlin
____________________________________________________________

Kevlin Henney phone: +44 117 942 2990
mailto:kev...@curbralan.com mobile: +44 7801 073 508
http://www.curbralan.com fax: +44 870 052 2289
Curbralan: Consultancy + Training + Development + Review
____________________________________________________________

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

johnchx

unread,
Apr 22, 2003, 7:04:30 AM4/22/03
to
Kevlin Henney <kev...@curbralan.com> wrote

>
> In clause 5 the standard specifies the example of interest as having
> unspecified behaviour. Any other interpretation is undefined ;->
>

A "bug report" has been filed with the standards committee against
those examples (Core Language Issue 351, status "drafting"). The
current direction seems to be "Find out what C99 says and do the same
thing."

Anyone know what C99 says about this?

Balog Pal

unread,
Apr 22, 2003, 7:04:52 AM4/22/03
to
"Francis Glassborow" <francis.g...@ntlworld.com> wrote in message news:O4Z2KkCl...@robinton.demon.co.uk...

> x = foo(i) + bar(i++);

> So, unless i is an


> object of a UDT, with an operator++() defined, such expressions can
> exhibit undefined behaviour.

That unless surprises me. Suppose i is a simple int wrapper, with op++ incrementing the single int member.

What is the defined behavior of the above expression? Will foo be called with the original or the incremented state of i?

Paul

Francis Glassborow

unread,
Apr 22, 2003, 12:00:17 PM4/22/03
to
In message <3ea4...@andromeda.datanet.hu>, Balog Pal <pa...@lib.hu>
writes

>"Francis Glassborow" <francis.g...@ntlworld.com> wrote in message news:O4Z2KkCl...@robinton.demon.co.uk...
>
> > x = foo(i) + bar(i++);
>
> > So, unless i is an
> > object of a UDT, with an operator++() defined, such expressions can
> > exhibit undefined behaviour.
>
>That unless surprises me. Suppose i is a simple int wrapper, with op++ incrementing the single int member.
>
>What is the defined behavior of the above expression? Will foo be called with the original or the incremented state o

Either, it is unspecified but what you will not get is undefined
behaviour. You must get one or other result but the reading and writing
of i cannot interlace and cause problems. Note that for built-in types
there is no such guarantee.


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

Terje Slettebø

unread,
Apr 22, 2003, 3:17:29 PM4/22/03
to
Francis Glassborow <francis.g...@ntlworld.com> wrote in message news:<O4Z2KkCl...@robinton.demon.co.uk>...
> Slettebø <"terjes."@chello.no.invalid> writes

> >However, as this is C++ code, with user-defined operators, there are
> >several sequence points (at least two per function call), so there's no
> >undefined behaviour.
>
> True, but no help for situations such as:
>
> x = foo(i) + bar(i++);

Having looked more into it, it seems that John Potter and Hyman Rosen
is right, after all.

Let's rewrite them, again, both the first example, and the example
above:

f(g(c),c++) // operator<<(operator<<(cout,c),c++)

f(g(c),h(c++)) // operator+(foo(i),bar(i++))

The reason I thought f(g(c),c++) didn't have undefined behaviour, was
that I was thinking that in order to evaluate g(c), it needs to call
the function, so if it evaluates g(c), then c++, then it's no
undefined behaviour. However, if it goes the other way, as John Potter
pointed out, then it may evaluate c++, c, then call g(c), and we would
have undefined behaviour. Since a valid sequence has undefined
behaviour, the whole expression has it.

However, in your example above, it needs to call a function, to
evaluate either of the arguments, which would then mean that there's a
sequence point between them, regardless of the order they are
evaluated. Therefore, it does not have undefined behaviour.

You say that the example above may have undefined behaviour, and if
you still think so, could you elaborate on why that is the case?


Regards,

Terje

Francis Glassborow

unread,
Apr 22, 2003, 3:18:53 PM4/22/03
to
In message <9e3a34f7.03042...@posting.google.com>, Terje
Slettebř <"terjes."@chello.no.invalid> writes

>I'm not sure if I understand the difference between this example, and
>the one at the start of this thread.
>
>If we rewrite them, we get (using non-member functions for clarity,
>and it shouldn't change the outcome, and likewise with assuming "+" is
>a user-defined operator):
>
>f(g(c),c++) // operator<<(operator<<(cout,c),c++)
>
>f(g(c),h(c++)) // operator+(foo(i),bar(i++))
>
>IIUC, you (and Kevlin Henney) say that the first doesn't have
>undefined, but unspecified behaviour, like I've said, but that new
>example here may have it.
>
>If either of them were to have undefined behaviour - due to 5.4 "the
>prior value shall be accessed only to determine the value to be
>stored", as Hyman Rosen quoted, it would mean that it can evaluate "c"
>and "c++", without an intervening sequence point.
>
>In what way are the above two expressions different, leading to this
>different outcome?

The critical feature is that if c is a UDT c++ must be provided by a
function and so the side effects of c++ must be complete before any
other evaluations.

So if c is a fundamental type both your statements have undefined
behaviour but if c is a UDT then the behaviour is unspecified.


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

Hyman Rosen

unread,
Apr 22, 2003, 3:19:31 PM4/22/03
to
Kevlin Henney wrote:
> that suggests that one of the examples,
> i = ++i + 1; // the behavior is unspecified
> should say "undefined"

This is number 351 of the C++ Standard Core Language Active Issues,
<http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#351>.

Hyman Rosen

unread,
Apr 22, 2003, 3:20:27 PM4/22/03
to
Balog Pal wrote:
> That unless surprises me. Suppose i is a simple int wrapper,
> with op++ incrementing the single int member.
> What is the defined behavior of the above expression?
> Will foo be called with the original or the incremented state of i?

You still don't know which it will be, but you do know that it will
be one or the other, because of the sequence points. The code will
look like
x = foo(i) + bar(i.op++(1));
You don't know whether i is passed to foo before or after the call
to i.op++(1), so the behavior is unspecified, but it's not undefined.

Sigh. Even the Standard has trouble with all of this
unspecified/undefined stupidity. Defined order now!

Kevlin Henney

unread,
Apr 22, 2003, 3:23:17 PM4/22/03
to
In article <us18avkcsqs6pgqdi...@4ax.com>, John Potter

<jpo...@falcon.lhup.edu> writes
>On 21 Apr 2003 09:09:26 -0400, Kevlin Henney <kev...@curbralan.com> wrote:
>
> > In article <iac3av0qoueq25cvc...@4ax.com>, John Potter
> > <jpo...@falcon.lhup.edu> writes
>
> > > cout << i << i++
>
> > >It is undefinded behavior.
>
> > In clause 5 the standard specifies the example of interest as having
> > unspecified behaviour. Any other interpretation is undefined ;->
>
>I assume that you are refering to 5/4 where the normative text states
>that it is undefined and the non-normative examples incorrectly label
>this as unspecified. See core issue 351.

Aha! That's the reference I needed -- I'm normally a library person, so
I missed the core issue. I think that clears it up for me -- the
standard was speaking with forked tongue :->

Kevlin
____________________________________________________________

Kevlin Henney phone: +44 117 942 2990
mailto:kev...@curbralan.com mobile: +44 7801 073 508
http://www.curbralan.com fax: +44 870 052 2289
Curbralan: Consultancy + Training + Development + Review
____________________________________________________________

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

James Kanze

unread,
Apr 22, 2003, 4:00:09 PM4/22/03
to
john...@yahoo.com (johnchx) wrote in message
news:<4fb4137d.03042...@posting.google.com>...
> Kevlin Henney <kev...@curbralan.com> wrote

> > In clause 5 the standard specifies the example of interest as
> > having unspecified behaviour. Any other interpretation is undefined
> > ;->

> A "bug report" has been filed with the standards committee against
> those examples (Core Language Issue 351, status "drafting"). The
> current direction seems to be "Find out what C99 says and do the same
> thing."

> Anyone know what C99 says about this?

The same thing as C90 (§6.5/2): "Between the previous and next sequence
point an object shall have its stored value modified at most once by the
evaluation of an expression. Furthermore, the prior value shall be read
on to determine the value to be stored."

In the expression:

f( i, i ++ ) ;

I is read twice and modified once. The first read (scanning lexically)
is NOT to determine the value stored by the modification. There is no
intervening sequence point.

This point is unchanged since the initial formulation of the C
standard. It is well known and documented in C circles. I can't
believe that there should be any doubt.

For more information, see questions 3.1-3.12 in the C FAQ
(http://www.eskimo.com/~scs/C-faq/s3.html).

(I'm not saying that this is the way it should be. Just that this is
the way it is.)

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

James Kanze

unread,
Apr 22, 2003, 4:02:45 PM4/22/03
to
terjes.@chello.no (Terje Slettebø) wrote in message
news:<9e3a34f7.03042...@posting.google.com>...

> Francis Glassborow <francis.g...@ntlworld.com> wrote in message
> news:<O4Z2KkCl...@robinton.demon.co.uk>...
> > In message <9e3a34f7.03041...@posting.google.com>, Terje
> > Sletteb <"terjes."@chello.no.invalid> writes
> > >However, as this is C++ code, with user-defined operators, there
> > >are several sequence points (at least two per function call), so
> > >there's no undefined behaviour.

> > True, but no help for situations such as:

> > x = foo(i) + bar(i++);

> > because the sequence points (after the evaluation of the arguments
> > and at the point of return -- even if the standard never mentioned
> > this second one unless the body of the function lacks any full
> > expressions) are too late to protect the evaluation of the two
> > arguments which may happen without any intervening sequence
> > points. So, unless i is an object of a UDT, with an operator++()
> > defined, such expressions can exhibit undefined behaviour.

> I'm not sure if I understand the difference between this example, and
> the one at the start of this thread.

I don't think there is any, but I'm not sure I remember the initial
example.

> If we rewrite them, we get (using non-member functions for clarity,
> and it shouldn't change the outcome, and likewise with assuming "+" is
> a user-defined operator):

> f(g(c),c++) // operator<<(operator<<(cout,c),c++)
>
> f(g(c),h(c++)) // operator+(foo(i),bar(i++))

> IIUC, you (and Kevlin Henney) say that the first doesn't have
> undefined, but unspecified behaviour, like I've said, but that new
> example here may have it.

Both expressions are equivalent with regards to undefined behavior. If
the variable c has a user defined type, with a user defined ++ operator,
the examples (both) have unspecified behavior. If the variable c is a
pointer or a basic type, both examples have undefined behavior.

The difference is that with a user defined ++, this particular
expression doesn't modify the variable, at least not directly. It
passes a reference to the variable to the function operator++, and uses
the return value of the fonction operator++. And both the call and the
return from operator++ create sequence points, which effectively isolate
any modifications to the variable made within the function.

Of course, even in this case, it is unspecified whether the first read
will occur before or after the call to operator++.

> If either of them were to have undefined behaviour - due to 5.4 "the
> prior value shall be accessed only to determine the value to be
> stored", as Hyman Rosen quoted, it would mean that it can evaluate "c"
> and "c++", without an intervening sequence point.

We can.

> In what way are the above two expressions different, leading to this
> different outcome?

They aren't.

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

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Kevlin Henney

unread,
Apr 23, 2003, 4:31:30 AM4/23/03
to
In article <mSRcAWTD...@robinton.demon.co.uk>, Francis Glassborow
<francis.g...@ntlworld.com> writes

>In message <3ea4...@andromeda.datanet.hu>, Balog Pal <pa...@lib.hu>
>writes
>>"Francis Glassborow" <francis.g...@ntlworld.com> wrote in message
>news:O4Z2KkCl...@robinton.demon.co.uk...
>>
>> > x = foo(i) + bar(i++);
>>
>> > So, unless i is an
>> > object of a UDT, with an operator++() defined, such expressions can
>> > exhibit undefined behaviour.
>>
>>That unless surprises me. Suppose i is a simple int wrapper, with op++
>incrementing the single int member.
>>
>>What is the defined behavior of the above expression? Will foo be called with
>the original or the incremented state o
>
>Either, it is unspecified but what you will not get is undefined
>behaviour. You must get one or other result but the reading and writing
>of i cannot interlace and cause problems. Note that for built-in types
>there is no such guarantee.

Assuming i to be a built-in type, the behaviour of the expression is
undefined according to my current understanding of the standard. It is
undefined because the requirement of [5/4] is that not only must a
scalar object have its value modified at most once, which is the case,
but the value must be accessed only to determine the value to be
updated, which is not the case. The value is accessed solely for use in
the call to foo as well as in postincrement for the call to bar.

Kevlin
____________________________________________________________

Kevlin Henney phone: +44 117 942 2990
mailto:kev...@curbralan.com mobile: +44 7801 073 508
http://www.curbralan.com fax: +44 870 052 2289
Curbralan: Consultancy + Training + Development + Review
____________________________________________________________

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

John Potter

unread,
Apr 23, 2003, 4:38:41 AM4/23/03
to
On 22 Apr 2003 16:02:45 -0400, ka...@gabi-soft.de (James Kanze) wrote:

> terjes.@chello.no (Terje Sletteb) wrote in message
> news:<9e3a34f7.03042...@posting.google.com>...

> > f(g(c),h(c++)) // operator+(foo(i),bar(i++))

> Both expressions are equivalent with regards to undefined behavior. If
> the variable c has a user defined type, with a user defined ++ operator,
> the examples (both) have unspecified behavior. If the variable c is a
> pointer or a basic type, both examples have undefined behavior.

A funny thing happened on the way to the newsgroup.

int f (int, int);
int g (const int&);
int h (int);
int c(21);
int p(f(g(c),h(c++)));

We have unspecified behavior because the access to c for other than
determining its new value is inside of g and protected by the sequence
points of the call. Pass by value and it is undefined behavior.

Amusing.

John

johnchx

unread,
Apr 23, 2003, 3:25:10 PM4/23/03
to
ka...@gabi-soft.de (James Kanze) wrote
> john...@yahoo.com (johnchx) wrote
> > Kevlin Henney <kev...@curbralan.com> wrote
>
> > > In clause 5 the standard specifies the example of interest as
> > > having unspecified behaviour. Any other interpretation is undefined
> > > ;->
>
> > A "bug report" has been filed with the standards committee against
> > those examples (Core Language Issue 351, status "drafting"). The
> > current direction seems to be "Find out what C99 says and do the same
> > thing."
>
> > Anyone know what C99 says about this?
>
> The same thing as C90 (§6.5/2): "Between the previous and next sequence
> point an object shall have its stored value modified at most once by the
> evaluation of an expression. Furthermore, the prior value shall be read
> on to determine the value to be stored."
>

Yes, but the question is whether the result of violating these rules
is undefined or unspecified. (Issue 351 is about the inconsistency
between the text of 5/4, which says "undefined," and the example
immediately following, which says "unspecified.")

My guess would be undefined...but without a copy of the C99 standard
in front of me, I can't tell for sure. Hence my question. :-)

Terje Slettebø

unread,
Apr 23, 2003, 3:28:55 PM4/23/03
to
John Potter <jpo...@falcon.lhup.edu> wrote in message news:<0dmbav8iogrogrh1o...@4ax.com>...

> On 22 Apr 2003 16:02:45 -0400, ka...@gabi-soft.de (James Kanze) wrote:
>
> > terjes.@chello.no (Terje Sletteb) wrote in message
> > news:<9e3a34f7.03042...@posting.google.com>...
>
> > > f(g(c),h(c++)) // operator+(foo(i),bar(i++))
>
> > Both expressions are equivalent with regards to undefined behavior. If
> > the variable c has a user defined type, with a user defined ++ operator,
> > the examples (both) have unspecified behavior. If the variable c is a
> > pointer or a basic type, both examples have undefined behavior.
>
> A funny thing happened on the way to the newsgroup.
>
> int f (int, int);
> int g (const int&);
> int h (int);
> int c(21);
> int p(f(g(c),h(c++)));
>
> We have unspecified behavior because the access to c for other than
> determining its new value is inside of g and protected by the sequence
> points of the call. Pass by value and it is undefined behavior.

I still wonder why it would be undefined behaviour in the case of pass
by value. To rewrite it like that:

int f (int, int);
int g (int); // Note


int h (int);
int c(21);
int p(f(g(c),h(c++)));

To evaluate f(), it needs to evaluate g(c) and h(h++). However, as I
understand, it can't interleave their evaluation.

To list some possibilities, like you did in an earlier posting:

Evaluate g(c)
-------------
Evaluate c
Call g()

Evaluate h(c++)
---------------
Evaluate c++
Call h()

Call f()

Or the other way around, for g(c) and h(c++).

In order to evaluate c and c++ right after each other, with no
intervening sequence point, it seems it would need to first partly
evaluate g(c) (only evaluating the c part, but not calling the
function), and then partially evaluate h(c++).

Can it do that? Any reference to the standard regarding this would
also be appreciated.


Regards,

Terje

Matthias Hofmann

unread,
Apr 24, 2003, 4:41:58 AM4/24/03
to

Terje Sletteb <terjes.@chello.no> schrieb in im Newsbeitrag:
9e3a34f7.03042...@posting.google.com...

Yes it can. The compiler is free to evaluate c and c++ in any order before
calling any of the functions in the example above. I don't quite understand
what you mean by "partly" - what usually happens is that the value of c and
c++ is pushed onto the stack, that's what evaluation means in practice.

John Potter

unread,
Apr 24, 2003, 4:46:36 AM4/24/03
to
On 23 Apr 2003 15:28:55 -0400, terjes.@chello.no (Terje Sletteb) wrote:

> In order to evaluate c and c++ right after each other, with no
> intervening sequence point, it seems it would need to first partly
> evaluate g(c) (only evaluating the c part, but not calling the
> function), and then partially evaluate h(c++).

> Can it do that? Any reference to the standard regarding this would
> also be appreciated.

Yes, it can do that. It can even evaluate c and c++ in parallel. The
reference is 5/4. The only thing that is restricted is execution of
a called function and a calling function which may not be interleaved.
All parameters to all functions may be evaluated before any function
is called. Note the word "subexpressions" in that paragraph. One way
to look at it is that a parse tree may be evaluated bottom up by layer.
In the absence of sequence points, the evaluations may be interleaved.
The difference between a function call and an operator like || is that
the latter forces left to right while the former only forces before and
after.

John

John Potter

unread,
Apr 24, 2003, 4:47:10 AM4/24/03
to
On 22 Apr 2003 15:17:29 -0400, terjes.@chello.no (Terje Sletteb) wrote:

> Francis Glassborow <francis.g...@ntlworld.com> wrote in message news:<O4Z2KkCl...@robinton.demon.co.uk>...

> > x = foo(i) + bar(i++);

> However, in your example above, it needs to call a function, to


> evaluate either of the arguments, which would then mean that there's a
> sequence point between them, regardless of the order they are
> evaluated. Therefore, it does not have undefined behaviour.

The order requirements are
i < foo < + < =
i < ++ < bar < + < =
Note the absence of any order on the two uses of i. Calling them
i1 and i2 gives the following possibilities.

i1 foo i2 ++ bar + =
i1 i2 foo ++ bar + =
i2 i1 foo ++ bar + =
i1 i2 ++ foo bar + =
i2 i1 ++ foo bar + =
i2 ++ i1 foo bar + =
i1 i2 ++ bar foo + =
i2 i1 ++ bar foo + =
i2 ++ i1 bar foo + =
i2 ++ bar i1 foo + =

Six of the orders have no sequence points between the accesses of i and ++.

John

James Kanze

unread,
Apr 24, 2003, 7:13:49 PM4/24/03
to
john...@yahoo.com (johnchx) wrote in message
news:<4fb4137d.03042...@posting.google.com>...

OK. ISO/IEC 9899:1999, §4/1,2:

In this International Standard, "shall" is to be interpreted as a
requirement on an implementation or on a program; conversely, "shall
not" is to be interpreted as a prohibition.

If a "shall" or "shall not" requirement that appears outside of a
constraint is violated, the behavior is undefined. Undefined
behavior is otherwise indicated in this International Standard by
the words "undefined behavior" or by the omission of any explicit
definition of behavior. There is no difference in emphasis among
these three; they all describe "behavior that is undefined".

In this case, we have a "shall" which is not part of a "constraint".

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

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

James Kanze

unread,
Apr 24, 2003, 7:15:27 PM4/24/03
to
terjes.@chello.no (Terje Slettebø) wrote in message
news:<9e3a34f7.03042...@posting.google.com>...

> John Potter <jpo...@falcon.lhup.edu> wrote in message
> news:<0dmbav8iogrogrh1o...@4ax.com>...
[...]

> I still wonder why it would be undefined behaviour in the case of pass
> by value. To rewrite it like that:

> int f (int, int);
> int g (int); // Note
> int h (int);
> int c(21);
> int p(f(g(c),h(c++)));

> To evaluate f(), it needs to evaluate g(c) and h(h++). However, as I
> understand, it can't interleave their evaluation.

Why not? §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."

In practice, about the only things that limit reordering are:

- causal necessity (in an expression like a + b, the compiler must
evaluate a and b before doing the addition), and

- sequence points (in the above, the call to h is a sequence point, so
the side effects of c++ must have taken place before the call).

Within an expression, these only introduce partial ordering. Thus, if
we consider the following simple operations: read c for g, read c for
incr, incr, store results of incr, call g, call h, call f, we have the
following ordering restrictions (using < to mean "must be before":

read c for g < call g causal necessity
read c for incr < incr causal necessity
incr < store results of incr causal necessity
incr < call h causal necessity
store results of incr < call h sequence point
call g < call f causal necessity
call h < call f causal necessity

(Those "causal necessity" before a function call could also be
attributed to the sequence point. But even without a sequence point,
they would be necessary.)

Any reordering which respects the above constraints is a legal execution
path for the abstract machine. If any legal execution path results in
undefined behavior, the behavior is undefined. Accessing a variable
that is modified without an intervening sequence point (e.g. a function
call) other than to determine the new value (which of course, introduces
implicit ordering due to causal necessity) is undefined behavior. (The
reasoning behind this rule is that in practice, even reading and writing
values are not atomic operations, and if there is no ordering
constraint, the compiler may schedule them such that they overlap.
Which really does give strange behavior on certain machines.)

In this case, one possible ordering is:

read c for incr
incr
store results of incr
read c for c
...

According to the standard, I have undefined behavior, because I have
read a variable (c) which is being modified, for a reason other than
determining the new value, and there is NO intervening sequence point.
The reason for this rule is that on some real hardware, the store and
the read above might overlap, and really give undefined behavior. (I
believe that at the time this issue was being discussed in the C
standard, someone pointed out a machine, perhaps only theoretical, in
which such a sequencing would result in a hardware deadlock.)

At any rate, the important thing to realize is that the ordering is only
partial. (At some point in the history of the C standard, there was
even a question as to whether the C standard allowed interleaving of the
two functions. After all, the function call to h isn't in any way
ordered by the sequence points in the call to g, and vice versa. The
decision of the C committee was that interleaving functions was illegal,
since it would effectively make the program act as if it were
multi-threaded.)

> To list some possibilities, like you did in an earlier posting:

Some isn't enough. The fact that there are one or two possibilities
which don't cause problems isn't enough.

> Evaluate g(c)
> -------------
> Evaluate c
> Call g()

> Evaluate h(c++)
> ---------------
> Evaluate c++
> Call h()

> Call f()

> Or the other way around, for g(c) and h(c++).

> In order to evaluate c and c++ right after each other, with no
> intervening sequence point, it seems it would need to first partly
> evaluate g(c) (only evaluating the c part, but not calling the
> function), and then partially evaluate h(c++).

> Can it do that?

Of course it can.

> Any reference to the standard regarding this would also be
> appreciated.

See above. Given that, the burden of proof is now on the other side:
you must show some passage ("otherwise noted") to forbid the specified
reordering. (In this case, I'm pretty sure that there isn't one.)

If I recall right, the classical example when the issue was being
discussed in C was something like:

(i++, j) + (j++, i)

The comma operators ensure sequence points. However, the sequence
points don't ensure any ordering between elements in the two
sub-expressions of the +. This expression thus has undefined behavior.

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

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

John Potter

unread,
Apr 24, 2003, 8:12:55 PM4/24/03
to
On 24 Apr 2003 19:15:27 -0400, ka...@gabi-soft.de (James Kanze) wrote:

> Any reordering which respects the above constraints is a legal execution
> path for the abstract machine. If any legal execution path results in
> undefined behavior, the behavior is undefined. Accessing a variable
> that is modified without an intervening sequence point (e.g. a function
> call) other than to determine the new value (which of course, introduces
> implicit ordering due to causal necessity) is undefined behavior.

You need to read a bit more carefully. It is only accessing the old value
the gives undefined behavior. Otherwise, j + ++ i would be undefined.

> In this case, one possible ordering is:
>
> read c for incr
> incr
> store results of incr
> read c for c

Put that last read at the top which is also allowed and you have undefined
behavior.

John

Terje Slettebø

unread,
Apr 25, 2003, 4:20:20 PM4/25/03
to
"Matthias Hofmann" <hof...@anvil-soft.com> wrote in message news:<3ea7065b$1...@news.nefonline.de>...

> Terje Sletteb <terjes.@chello.no> schrieb in im Newsbeitrag:
> 9e3a34f7.03042...@posting.google.com...
> > John Potter <jpo...@falcon.lhup.edu> wrote in message
> news:<0dmbav8iogrogrh1o...@4ax.com>...
> > > On 22 Apr 2003 16:02:45 -0400, ka...@gabi-soft.de (James Kanze) wrote:
> > In order to evaluate c and c++ right after each other, with no
> > intervening sequence point, it seems it would need to first partly
> > evaluate g(c) (only evaluating the c part, but not calling the
> > function), and then partially evaluate h(c++).
> >
> > Can it do that? Any reference to the standard regarding this would
> > also be appreciated.
>
> Yes it can. The compiler is free to evaluate c and c++ in any order before
> calling any of the functions in the example above. I don't quite understand
> what you mean by "partly"

I meant what I wrote, that in order to evaluate g(c), it has to:

evaluate c
call g()

John Potter also confirmed in another posting that it can do what you
say, here:

evaluate c
evaluate c++
call g()

In other words, it can evaluate the expression g(c) interleaved with
another, or partly evaluate it (only evaluate c), before evaluating
another.


Regards,

Terje

Matthias Hofmann

unread,
Apr 25, 2003, 6:24:08 PM4/25/03
to

James Kanze <ka...@gabi-soft.de> schrieb in im Newsbeitrag:
d6651fb6.03042...@posting.google.com...
> terjes.@chello.no (Terje Slettebř) wrote in message

> news:<9e3a34f7.03042...@posting.google.com>...
> > John Potter <jpo...@falcon.lhup.edu> wrote in message
> > news:<0dmbav8iogrogrh1o...@4ax.com>...
> [...]
> If I recall right, the classical example when the issue was being
> discussed in C was something like:
>
> (i++, j) + (j++, i)
>
> The comma operators ensure sequence points. However, the sequence
> points don't ensure any ordering between elements in the two
> sub-expressions of the +. This expression thus has undefined behavior.

As far as I know, the commas separating parameters in a function call have
nothing to do with the comma operator. Hence, there is no sequence point
between i++ and j (or between j++ and i ).

John Potter

unread,
Apr 26, 2003, 12:46:14 PM4/26/03
to
On 25 Apr 2003 18:24:08 -0400, "Matthias Hofmann" <hof...@anvil-soft.com>
wrote:

> James Kanze <ka...@gabi-soft.de> schrieb in im Newsbeitrag:
> d6651fb6.03042...@posting.google.com...

> > If I recall right, the classical example when the issue was being


> > discussed in C was something like:
> >
> > (i++, j) + (j++, i)
> >
> > The comma operators ensure sequence points. However, the sequence
> > points don't ensure any ordering between elements in the two
> > sub-expressions of the +. This expression thus has undefined behavior.

> As far as I know, the commas separating parameters in a function call have
> nothing to do with the comma operator.

That is correct; however, there is no function call in the above. It has
two primary-expressions of the form ( expression ) and those are comma
operators.

plus((i++, j), (j++, i))

has two comma operators in the two argument expressions and one comma
separator in the expression-list.

John

Terje Slettebø

unread,
Apr 26, 2003, 12:54:40 PM4/26/03
to
ka...@gabi-soft.de (James Kanze) wrote in message news:<d6651fb6.03042...@posting.google.com>...

> terjes.@chello.no (Terje Slettebø) wrote in message
> news:<9e3a34f7.03042...@posting.google.com>...
>
> > int f (int, int);
> > int g (int); // Note
> > int h (int);
> > int c(21);
> > int p(f(g(c),h(c++)));
>
> > To evaluate f(), it needs to evaluate g(c) and h(h++). However, as I
> > understand, it can't interleave their evaluation.
>
> Why not? §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."
>
> > Any reference to the standard regarding this would also be
> > appreciated.
>
> See above. Given that, the burden of proof is now on the other side:
> you must show some passage ("otherwise noted") to forbid the specified
> reordering. (In this case, I'm pretty sure that there isn't one.)

No, I understand now that this is allowed.

What made me be pretty sure it was unspecified, not undefined
behaviour, is that this exact example was discussed at the
accu-general mailing list a while before this thread, where several
experienced people participated, and the consensus was that it has
unspecified behaviour.

The origin was an interview question: What is the output of the
following program?

#include <iostream>
#include <ostream>

int main()
{
int c = 0;
std::cout << c++ << c;
};

The choices were:

A) 00
B) 01
C) Unspecified

As is shown, "Undefined" wasn't even listed as an option. :) It just
goes to show that even experts may have problems with this one.


Regards,

Terje

Kevlin Henney

unread,
Apr 27, 2003, 7:58:55 AM4/27/03
to
In article <3ea9...@news.nefonline.de>, Matthias Hofmann
<hof...@anvil-soft.com> writes

>
>James Kanze <ka...@gabi-soft.de> schrieb in im Newsbeitrag:
>d6651fb6.03042...@posting.google.com...
>> If I recall right, the classical example when the issue was being
>> discussed in C was something like:
>>
>> (i++, j) + (j++, i)
>>
>> The comma operators ensure sequence points. However, the sequence
>> points don't ensure any ordering between elements in the two
>> sub-expressions of the +. This expression thus has undefined behavior.
>
>As far as I know, the commas separating parameters in a function call have
>nothing to do with the comma operator.

Correct.

>Hence, there is no sequence point
>between i++ and j (or between j++ and i ).

Incorrect. Assuming i and j to be scalars, there are no function calls
involved, and the expression uses the comma operator twice. Note that
the example is

(i++, j) + (j++, i)

and not

f(i++, j) + g(j++, i)

Kevlin
____________________________________________________________

Kevlin Henney phone: +44 117 942 2990
mailto:kev...@curbralan.com mobile: +44 7801 073 508
http://www.curbralan.com fax: +44 870 052 2289
Curbralan: Consultancy + Training + Development + Review
____________________________________________________________

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Matthias Hofmann

unread,
Apr 28, 2003, 3:37:26 PM4/28/03
to

Kevlin Henney <kev...@curbralan.com> schrieb in im Newsbeitrag:
jqyc$SCTCr...@curbralan.com...

> In article <3ea9...@news.nefonline.de>, Matthias Hofmann
> <hof...@anvil-soft.com> writes
> >
> >James Kanze <ka...@gabi-soft.de> schrieb in im Newsbeitrag:
> >d6651fb6.03042...@posting.google.com...
> Correct.
>
> >Hence, there is no sequence point
> >between i++ and j (or between j++ and i ).
>
> Incorrect. Assuming i and j to be scalars, there are no function calls
> involved, and the expression uses the comma operator twice. Note that
> the example is
>
> (i++, j) + (j++, i)
>
> and not
>
> f(i++, j) + g(j++, i)

Oops - how embarassing! I was so confused by all the information in this
thread that I saw a function call while there wasn't any...

Kevlin Henney

unread,
Apr 29, 2003, 2:53:48 PM4/29/03
to
In article <3ead...@news.nefonline.de>, Matthias Hofmann
<hof...@anvil-soft.com> writes
>

>Kevlin Henney <kev...@curbralan.com> schrieb in im Newsbeitrag:
> Note that
>> the example is
>>
>> (i++, j) + (j++, i)
>>
>> and not
>>
>> f(i++, j) + g(j++, i)
>
>Oops - how embarassing! I was so confused by all the information in this
>thread that I saw a function call while there wasn't any...

There is always the chance that you could have assumed that whitespace
was being overloaded... but I guess it's the wrong end of April for that
;-)

Kevlin
____________________________________________________________

Kevlin Henney phone: +44 117 942 2990
mailto:kev...@curbralan.com mobile: +44 7801 073 508
http://www.curbralan.com fax: +44 870 052 2289
Curbralan: Consultancy + Training + Development + Review
____________________________________________________________

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

0 new messages