# x=x*x vs. i=i++

Discussion in 'C++' started by al.cpwn@gmail.com, Mar 22, 2006.

1. ### Guest

why is i=i++ undefined while x=x*x is alright?

, Mar 22, 2006

2. ### peter kochGuest

skrev:

> why is i=i++ undefined while x=x*x is alright?

Because i=i++ contains to assignments to i. x=x*x only contains one
assignment to x.
It is when the same variable has two assignments without an intervening
sequenceproblem, you get into troubles.

Peter

peter koch, Mar 22, 2006

3. ### Mark PGuest

peter koch wrote:
> skrev:
>
>> why is i=i++ undefined while x=x*x is alright?

>
> Because i=i++ contains to assignments to i. x=x*x only contains one
> assignment to x.
> It is when the same variable has two assignments without an intervening
> sequenceproblem, you get into troubles.
>
> Peter
>

Out of curiousity, what about i = ++i? In this case it at least seems
that both assignments do the same thing.

Mark P, Mar 22, 2006
4. ### Clark S. Cox IIIGuest

On 2006-03-21 21:04:16 -0500, Mark P
<> said:

> peter koch wrote:
>> skrev:
>>
>>> why is i=i++ undefined while x=x*x is alright?

>>
>> Because i=i++ contains to assignments to i. x=x*x only contains one
>> assignment to x.
>> It is when the same variable has two assignments without an intervening
>> sequenceproblem, you get into troubles.
>>
>> Peter
>>

>
> Out of curiousity, what about i = ++i? In this case it at least seems
> that both assignments do the same thing.

It doesn't matter if they "do the same thing". The fact that there are
two of them makes it undefined behavior.

--
Clark S. Cox, III

Clark S. Cox III, Mar 22, 2006
5. ### CodeCrackerGuest

I think that in case of
i = i++ the problem is when to assign the incremented value of i to i.
Just for clarity if I define i on the left of equality as Li and on the
right of equality as Ri and rewrite the statement then
Li = Ri++;
This line will be executed as follows:
a. Get the value of Ri.
b. Should I assign the output of ++ operator on Ri now?
c. Assign Ri to Li
d. Or should I assign the incremented value of Ri to Ri now?
Since the C++ standard is not clear on this compiler author can
implement it in either of two ways and consequently the difference in
output is possible.
But if I write
Li = ++Ri;
then the intention is very clear. The steps in this case will be
a. Increment Ri
b. Get the value of incremented Ri
c: assign this new value of Ri to Li

I don't think there will be any problem in this second case.

CodeCracker, Mar 22, 2006
6. ### AnalogFileGuest

CodeCracker wrote:
> I think that in case of
> i = i++ the problem is when to assign the incremented value of i to i.
> Just for clarity if I define i on the left of equality as Li and on the
> right of equality as Ri and rewrite the statement then
> Li = Ri++;
> This line will be executed as follows:
> a. Get the value of Ri.
> b. Should I assign the output of ++ operator on Ri now?
> c. Assign Ri to Li
> d. Or should I assign the incremented value of Ri to Ri now?
> Since the C++ standard is not clear on this compiler author can
> implement it in either of two ways and consequently the difference in
> output is possible.
> But if I write
> Li = ++Ri;
> then the intention is very clear. The steps in this case will be
> a. Increment Ri
> b. Get the value of incremented Ri
> c: assign this new value of Ri to Li
>
> I don't think there will be any problem in this second case.

What you think is not really relevant.

#include <iostream>
#include <ostream>

int main()
{
int i=1;
i=++i;
std::cout << i;
}

if you compile and execute and it outputs 42 the compiler is not broken
and is behaving according to the standard.

AnalogFile, Mar 22, 2006
7. ### hnaikGuest

I think because:

i++ means i += 1
whereas:
x*x is just an expression.

hnaik, Mar 22, 2006
8. ### Gernot FrischGuest

> why is i=i++ undefined while x=x*x is alright?

Just don't do it - it's stupid anyway.

Gernot Frisch, Mar 22, 2006
9. ### Rolf MagnusGuest

wrote:

> why is i=i++ undefined while x=x*x is alright?

i++ writes to i, x*x doesn't write to x.

Rolf Magnus, Mar 22, 2006
10. ### Gavin DeaneGuest

CodeCracker wrote:
> I think that in case of
> i = i++ the problem is when to assign the incremented value of i to i.
> Just for clarity if I define i on the left of equality as Li and on the
> right of equality as Ri and rewrite the statement then
> Li = Ri++;
> This line will be executed as follows:
> a. Get the value of Ri.
> b. Should I assign the output of ++ operator on Ri now?
> c. Assign Ri to Li
> d. Or should I assign the incremented value of Ri to Ri now?
> Since the C++ standard is not clear on this compiler author can
> implement it in either of two ways and consequently the difference in
> output is possible.

The C++ standard is perfectly clear. Modifying a value more than once
between sequence points gives undefined behaviour. The compiler could
implement it in either of the two ways you suggest. Or the compiler
could do absolutely anything else it likes.

> But if I write
> Li = ++Ri;
> then the intention is very clear. The steps in this case will be
> a. Increment Ri
> b. Get the value of incremented Ri
> c: assign this new value of Ri to Li

Why do you think those will be the steps, rather than, for eaxmple:

a. Evaluate the expression ++Ri (the value will be Ri + 1)
b. Should I assign the value of the expression ++Ri to Ri now?
c. Assign Ri to Li, but what is the value of Ri?
d. Or should I assign the value of the expression ++Ri to Ri now?

> I don't think there will be any problem in this second case.

There is exactly the same problem with the second case as with the
first. Undefined behaviour.

Gavin Deane

Gavin Deane, Mar 22, 2006
11. ### Pete BeckerGuest

CodeCracker wrote:
> Since the C++ standard is not clear on this compiler author can
> implement it in either of two ways and consequently the difference in
> output is possible.

The C++ Standard is quite clear: the behavior of that code is undefined.
That means that the standard does not require any particular behavior
from that code. It's certainly reasonable for a compiler to do what you
suggest, but unless the compiler's documentation tells you that that's
what it does or you've tested it, you're just speculating.

--

Pete Becker
Roundhouse Consulting, Ltd.

Pete Becker, Mar 22, 2006
12. ### Guest

There is no way that a serious c++ compiler could generate a code wich
output is 42, I'm using GCC 3.4.4 and the output is 2.

, Mar 22, 2006
13. ### Gavin DeaneGuest

wrote:
> There is no way that a serious c++ compiler could generate a code wich
> output is 42, I'm using GCC 3.4.4 and the output is 2.

I think you missed the point.

Given this program

#include <iostream>
#include <ostream>

int main()
{
int i=1;
i=++i;
std::cout << i;
}

42 might be a less *likely* output than 2. But the point is that 42 is
just as *valid* as 2. Any output is as valid as any other. It is
unfortunate that sometimes when you invoke undefined behaviour, you see
exactly the effect you were expecting.

Gavin Deane

Gavin Deane, Mar 22, 2006
14. ### Richard HerringGuest

In message <>,
"" <> writes
>There is no way that a serious c++ compiler could generate a code wich
>output is 42,

A truly serious C++ compiler would refuse to compile such abominations
in the first place.

>I'm using GCC 3.4.4 and the output is 2.

So what? According to the C++ standard it's at liberty to produce any
effects it likes.

--
Richard Herring

Richard Herring, Mar 22, 2006
15. ### Pete BeckerGuest

Gavin Deane wrote:
>
> 42 might be a less *likely* output than 2. But the point is that 42 is
> just as *valid* as 2.

It's valid according to the language definition. In fact, a compiler
will produce one of the two results that have been mentioned. The reason
the standard doesn't require one or the other is that this provision
applies to any code that modifies the same value more than once between
sequence points, so it's hard to write an exact specification of the
possible results. Aside from whether it is well-defined, either in
theory or in practice, though, this code is nonsense. Even if it were
well defined it has no reason to exist.

--

Pete Becker
Roundhouse Consulting, Ltd.

Pete Becker, Mar 22, 2006
16. ### Gernot FrischGuest

> There is no way that a serious c++ compiler could generate a code
> wich
> output is 42, I'm using GCC 3.4.4 and the output is 2.

LOL! If I were to write one, it would!

Gernot Frisch, Mar 22, 2006
17. ### AnalogFileGuest

wrote:
> There is no way that a serious c++ compiler could generate a code wich
> output is 42, I'm using GCC 3.4.4 and the output is 2.
>

That's why Deep Thought will not be compiled with version 3.4.4.

When the ever increasing compilation times of GCC will top 7.5 million
years, it will.

AnalogFile, Mar 22, 2006
18. ### Gernot FrischGuest

"AnalogFile" <> schrieb im Newsbeitrag
news:gYdUf.26424\$...
> wrote:
>> There is no way that a serious c++ compiler could generate a code
>> wich
>> output is 42, I'm using GCC 3.4.4 and the output is 2.
>>

>
> That's why Deep Thought will not be compiled with version 3.4.4.
>
> When the ever increasing compilation times of GCC will top 7.5
> million years, it will.

This is one of the world-wide known jokes - long before the internet.

Gernot Frisch, Mar 22, 2006
19. ### AnalogFileGuest

Gernot Frisch wrote:
> "AnalogFile" <> schrieb im Newsbeitrag
> news:gYdUf.26424\$...
>> wrote:
>>> There is no way that a serious c++ compiler could generate a code
>>> wich
>>> output is 42, I'm using GCC 3.4.4 and the output is 2.
>>>

>> That's why Deep Thought will not be compiled with version 3.4.4.
>>
>> When the ever increasing compilation times of GCC will top 7.5
>> million years, it will.

>
> This is one of the world-wide known jokes - long before the internet.
>

Did not mean to be original.
But suspect serghei didn't actually recognize the philosophical
implications of my example (I know you did, from your earlier reply).
I just wanted to give him more keywords to google for.

oh, wait!
You actually mean GCC was faster in pre internet? ;-)

AnalogFile, Mar 22, 2006
20. ### Guest

CodeCracker wrote:
> I think that in case of
> i = i++ the problem is when to assign the incremented value of i to i.
> Just for clarity if I define i on the left of equality as Li and on the
> right of equality as Ri and rewrite the statement then
> Li = Ri++;
> This line will be executed as follows:
> a. Get the value of Ri.
> b. Should I assign the output of ++ operator on Ri now?
> c. Assign Ri to Li
> d. Or should I assign the incremented value of Ri to Ri now?
> Since the C++ standard is not clear on this compiler author can
> implement it in either of two ways and consequently the difference in
> output is possible.
> But if I write
> Li = ++Ri;
> then the intention is very clear. The steps in this case will be
> a. Increment Ri
> b. Get the value of incremented Ri
> c: assign this new value of Ri to Li
>

Not quite. Here are the semantics for the pre- and postincrement
operators as applied to scalar types:

i++: evaluate to i, and sometime before the next sequence point,
increment i.
++i: evaluate to i+1, and sometime before the next sequence point,
increment i.

You can't make any assumptions about when the side effect is actually
applied, other than it must be before the next sequence point. The
second case can evaluate as

tmp <- Ri + 1
Ri <- Ri + 1
Li <- tmp

or

tmp <- Ri + 1
Li <- tmp
Ri <- Ri + 1

or

Ri <- Ri + 1
Li <- Ri

or even something else entirely, as long as the semantics are
preserved.

> I don't think there will be any problem in this second case.

The second case has the exact same problem as the first case, at least
if you're dealing with scalar types. "i = ++i" is just as undefined as
"i = i++".

, Mar 22, 2006