Unpredictable result of Increment operation

Discussion in 'C++' started by bintom, May 9, 2008.

  1. bintom

    bintom Guest

    Is there any reason why the following C++ code behaves as it does ?



    int i;

    i=1; cout << (++i)++; Output: 2

    i=1; cout << ++(++i); Output: 3

    i=1; cout << (i++)++; Output: Error. LValue required

    i=1; cout << ++(i++); Output: Error. LValue required
    bintom, May 9, 2008
    #1
    1. Advertising

  2. bintom

    Ian Collins Guest

    bintom wrote:
    > Is there any reason why the following C++ code behaves as it does ?
    >
    >
    >
    > int i;
    >
    > i=1; cout << (++i)++; Output: 2
    >

    Because it's nonsensical undefined behaviour.

    --
    Ian Collins.
    Ian Collins, May 9, 2008
    #2
    1. Advertising

  3. bintom

    Ian Collins Guest

    Victor Bazarov wrote:
    > Ian Collins wrote:
    >> bintom wrote:
    >>> Is there any reason why the following C++ code behaves as it does ?
    >>>
    >>>
    >>>
    >>> int i;
    >>>
    >>> i=1; cout << (++i)++; Output: 2
    >>>

    >> Because it's nonsensical undefined behaviour.

    >
    > Why is it non-sensical? Why is it undefined?
    >

    You are right, it is neither. Sorry, I've seen way too many posts that
    are and do...

    --
    Ian Collins.
    Ian Collins, May 9, 2008
    #3
  4. bintom

    bintom Guest

    Hi Jack,

    Thank for your inputs on undefined/invalid uses (rather than
    unpredictable results) of ++ operator. It was a great help.

    bintom
    bintom, May 9, 2008
    #4
  5. bintom

    James Kanze Guest

    On May 9, 2:54 am, "Victor Bazarov" <> wrote:
    > Ian Collins wrote:
    > > bintom wrote:
    > >> Is there any reason why the following C++ code behaves as it does ?


    > >> int i;


    > >> i=1; cout << (++i)++; Output: 2


    > > Because it's nonsensical undefined behaviour.


    > Why is it non-sensical? Why is it undefined?


    Because the standard says so. You're modifying the same object
    twice without an intervening sequence point.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, May 9, 2008
    #5
  6. bintom

    brno Guest

    James Kanze dixit:
    > On May 9, 2:54 am, "Victor Bazarov" <> wrote:
    >> Ian Collins wrote:
    >>> bintom wrote:
    >>>> Is there any reason why the following C++ code behaves as it does ?

    >
    >>>> int i;

    >
    >>>> i=1; cout << (++i)++; Output: 2

    >
    >>> Because it's nonsensical undefined behaviour.

    >
    >> Why is it non-sensical? Why is it undefined?

    >
    > Because the standard says so. You're modifying the same object
    > twice without an intervening sequence point.


    Can you tell what is an intervening sequence point ?

    Thanks
    brno, May 10, 2008
    #6
  7. bintom

    Ian Collins Guest

    Ian Collins wrote:
    > Victor Bazarov wrote:
    >> Ian Collins wrote:
    >>> bintom wrote:
    >>>> Is there any reason why the following C++ code behaves as it does ?
    >>>>
    >>>>
    >>>>
    >>>> int i;
    >>>>
    >>>> i=1; cout << (++i)++; Output: 2
    >>>>
    >>> Because it's nonsensical undefined behaviour.

    >> Why is it non-sensical? Why is it undefined?
    >>

    > You are right, it is neither. Sorry, I've seen way too many posts that
    > are and do...
    >

    Um, undefined behaviour overload. I was right the first time...

    --
    Ian Collins.
    Ian Collins, May 10, 2008
    #7
  8. bintom

    Ian Collins Guest

    brno wrote:
    > James Kanze dixit:
    >> On May 9, 2:54 am, "Victor Bazarov" <> wrote:
    >>> Ian Collins wrote:
    >>>> bintom wrote:
    >>>>> Is there any reason why the following C++ code behaves as it does ?

    >>
    >>>>> int i;

    >>
    >>>>> i=1; cout << (++i)++; Output: 2

    >>
    >>>> Because it's nonsensical undefined behaviour.

    >>
    >>> Why is it non-sensical? Why is it undefined?

    >>
    >> Because the standard says so. You're modifying the same object
    >> twice without an intervening sequence point.

    >
    > Can you tell what is an intervening sequence point ?
    >

    A sequence point occurs after the evaluation of a full expression.
    "(++i)++;" is an expression with two modifications of i.

    --
    Ian Collins.
    Ian Collins, May 10, 2008
    #8
  9. bintom

    James Kanze Guest

    On 10 mai, 10:34, brno <> wrote:
    > James Kanze dixit:


    > > On May 9, 2:54 am, "Victor Bazarov" <> wrote:
    > >> Ian Collins wrote:
    > >>> bintom wrote:
    > >>>> Is there any reason why the following C++ code behaves as it does ?


    > >>>> int i;


    > >>>> i=1; cout << (++i)++; Output: 2


    > >>> Because it's nonsensical undefined behaviour.


    > >> Why is it non-sensical? Why is it undefined?


    > > Because the standard says so. You're modifying the same object
    > > twice without an intervening sequence point.


    > Can you tell what is an intervening sequence point ?


    A sequence point that is guaranteed to occur between the two
    operations.

    In your example, the only sequence points are the ends of each
    full expression, and the call and return from the
    ostream::eek:perator<<( int ) function. There's nothing between
    the ++i (which modifies i), and the (x)++ (where 'x' is the
    result of ++i, i.e. i), which also modifies i.

    Note that if i was a type with a user defined operator++, the
    code would be well defined, since the user defined operator++ is
    a function, and both the function call and the return are
    sequence points. Note too, however, that sequence points do not
    always create a complete ordering: in something like 'f(++i) +
    g(++i)', there are still no sequence points between the two
    incrementations, so the code has undefined behavior.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, May 10, 2008
    #9
  10. bintom

    James Kanze Guest

    On 10 mai, 15:47, "Victor Bazarov" <> wrote:

    > A sequence point is a definite *moment* in the execution of the
    > program, at which all the side effects of the previous calculations
    > have taken place. There are several situations in which a sequence
    > point (SP) is known to exist. First, there is a SP at a semicolon.
    > There is a SP after evaluation of all arguments of a function and
    > just before the call to that function. There is another SP right
    > after the function returns. There is another SP after each object
    > is initialised in a definition statement. A comma operator also
    > introduces a SP, and so does every logical OR and logical AND
    > operator. I think that's about it. I don't think there are other
    > sequence points defined.


    In 'a ? b : c', between the evaluation of a and either b or c.

    > The concept of a sequence point is important for allowing the C++
    > compiler to create certain optimizations when it generates code
    > from a C++ program. Sequence points are a limitation on the
    > execution of the program, so too many of those would mean the
    > code cannot be optimized. Too few of them might mean the code
    > won't behave predictably.


    It's also important to realize that the compiler can reorder
    code in an expression significantly, and if any of the legal
    reorderings violate the rules, you have undefined behavior. The
    classical example is something like:
    f( ++ i ) + g( ++ i ) ;
    Undefined behavior, since the compiler can legally reorder this
    to be as:
    tmp1 = ++ i
    tmp2 = ++ i
    f( tmp1 )
    g( tmp2 )
    (without any sequence points other than the function calls).

    In practice, I (and I suspect that I'm not alone) find it almost
    impossible to be 100% sure whether there is a sequence point or
    not in some of the more subtle cases. So the general rule is to
    just avoid modifying the same variable more than once in an
    expression, or modifying it and using it elsewhere in the
    expression. About the only exceptions I'll allow are for top
    level (not in any parentheses) &&, || and ?:.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, May 10, 2008
    #10
    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.
Similar Threads
  1. Replies:
    104
    Views:
    10,937
    Jordan Abel
    Oct 28, 2005
  2. Replies:
    99
    Views:
    2,479
    eliza81
    Jun 11, 2010
  3. bintom
    Replies:
    10
    Views:
    666
    James Kanze
    May 11, 2008
  4. Alf P. Steinbach /Usenet
    Replies:
    0
    Views:
    879
    Alf P. Steinbach /Usenet
    May 22, 2011
  5. Michael Tan
    Replies:
    32
    Views:
    937
    Ara.T.Howard
    Jul 21, 2005
Loading...

Share This Page