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
    #1
    1. Advertising

  2. peter koch Guest

    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
    #2
    1. Advertising

  3. Mark P Guest

    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
    #3
  4. 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
    #4
  5. CodeCracker Guest

    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
    #5
  6. AnalogFile 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
    >
    > 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
    #6
  7. hnaik Guest

    I think because:

    i++ means i += 1
    there is already an assignment
    whereas:
    x*x is just an expression.
     
    hnaik, Mar 22, 2006
    #7

  8. > 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
    #8
  9. Rolf Magnus Guest

    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
    #9
  10. Gavin Deane 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.


    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
    #10
  11. Pete Becker Guest

    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
    #11
  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
    #12
  13. Gavin Deane Guest

    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
    #13
  14. 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
    #14
  15. Pete Becker Guest

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

  16. > 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
    #16
  17. AnalogFile Guest

    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
    #17
  18. "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
    #18
  19. AnalogFile Guest

    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
    #19
  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
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page