std::cout << x << " " << x++ << std::endl

Discussion in 'C++' started by Filipe Sousa, Feb 5, 2006.

  1. Filipe Sousa

    Filipe Sousa Guest

    Hi!

    Could someone explain to me why this operation is not what I was expecting?

    int main()
    {
    int x = 2;
    std::cout << x << " " << x++ << std::endl;
    return 0;
    }

    main.cc: In function 'int main()':
    warning: operation on 'x' may be undefined

    The result is
    3 2

    I would expect 2 2.

    Thanks
    Filipe Sousa
    Filipe Sousa, Feb 5, 2006
    #1
    1. Advertising

  2. Filipe Sousa

    Kai-Uwe Bux Guest

    Filipe Sousa wrote:

    > Hi!
    >
    > Could someone explain to me why this operation is not what I was
    > expecting?
    >
    > int main()
    > {
    > int x = 2;
    > std::cout << x << " " << x++ << std::endl;


    This is equivalent to:

    operator<< (
    operator<< (
    operator<< (
    operator<< ( std::cout, x ),
    " "
    ),
    x++
    ),
    std::endl;
    );

    In such an expression, the order of evaluation of subexpressions is
    implementation defined. In particular, there is no guarantee that

    operator<<( std::cout, x )

    will be evaluated before

    x++



    > return 0;
    > }
    >
    > main.cc: In function 'int main()':
    > warning: operation on 'x' may be undefined
    >
    > The result is
    > 3 2


    That is just one possible result.

    > I would expect 2 2.


    That is another possible result.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Feb 5, 2006
    #2
    1. Advertising

  3. Filipe Sousa wrote:
    > Hi!
    >
    > Could someone explain to me why this operation is not what I was expecting?
    >
    > int main()
    > {
    > int x = 2;
    > std::cout << x << " " << x++ << std::endl;
    > return 0;
    > }
    >
    > main.cc: In function 'int main()':
    > warning: operation on 'x' may be undefined
    >
    > The result is
    > 3 2
    >
    > I would expect 2 2.
    >
    > Thanks
    > Filipe Sousa


    The result is undefined for your example. This is because x++ could
    compiled to increment after the whole statement or immediately after use
    as in this case. In short if you want predictable behaviour when using
    operator ++ then the variable it is applied to should only appear once
    in the expression being evaluated.

    JB
    n2xssvv g02gfr12930, Feb 5, 2006
    #3
  4. Filipe Sousa

    TB Guest

    Filipe Sousa sade:
    > Hi!
    >
    > Could someone explain to me why this operation is not what I was expecting?
    >
    > int main()
    > {
    > int x = 2;
    > std::cout << x << " " << x++ << std::endl;
    > return 0;
    > }
    >
    > main.cc: In function 'int main()':
    > warning: operation on 'x' may be undefined
    >
    > The result is
    > 3 2
    >
    > I would expect 2 2.
    >
    > Thanks
    > Filipe Sousa


    http://www.parashift.com/c -faq-lite/misc-technical-issues.html#faq-39.16

    --
    TB @ SWEDEN
    TB, Feb 5, 2006
    #4
  5. Filipe Sousa

    Kai-Uwe Bux Guest

    TB wrote:

    > Filipe Sousa sade:
    >> Hi!
    >>
    >> Could someone explain to me why this operation is not what I was
    >> expecting?
    >>
    >> int main()
    >> {
    >> int x = 2;
    >> std::cout << x << " " << x++ << std::endl;
    >> return 0;
    >> }
    >>
    >> main.cc: In function 'int main()':
    >> warning: operation on 'x' may be undefined
    >>
    >> The result is
    >> 3 2
    >>
    >> I would expect 2 2.
    >>
    >> Thanks
    >> Filipe Sousa

    >
    > http://www.parashift.com/c -faq-lite/misc-technical-issues.html#faq-39.16
    >


    I think, this is *not* a matter of sequence points. The expression is
    equivalent to:

    operator<< (
    operator<< (
    operator<< (
    operator<< ( std::cout, x ),
    " "
    ),
    x++
    ),
    std::endl;
    );

    and the various function calls provide sufficiently many sequence points.

    The results are implementation defined because the evaluation order of the
    parameters passed in a function call is implementation defined.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Feb 5, 2006
    #5
  6. On Sun, 05 Feb 2006 18:27:38 +0000, n2xssvv g02gfr12930 wrote:

    > Filipe Sousa wrote:
    >>
    >> Could someone explain to me why this operation is not what I was
    >> expecting?
    >>
    >> int main()
    >> {
    >> int x = 2;
    >> std::cout << x << " " << x++ << std::endl; return 0;
    >> }

    >
    > The result is undefined for your example. This is because x++ could
    > compiled to increment after the whole statement or immediately after use
    > as in this case. In short if you want predictable behaviour when using
    > operator ++ then the variable it is applied to should only appear once in
    > the expression being evaluated.


    TB's reference to sequence points[1] sits better as a reply to this
    remark because, while this is excellent advice for beginners, it is not
    entirely true due to expressions like x++ || x++ which have, I think,
    predictable behaviour (however daft they may be in practice).

    [1]
    http://www.parashift.com/c -faq-lite/misc-technical-issues.html#faq-39.16

    --
    Ben.
    Ben Bacarisse, Feb 5, 2006
    #6
  7. Filipe Sousa

    Jack Klein Guest

    On Sun, 05 Feb 2006 19:23:40 +0000, Ben Bacarisse
    <> wrote in comp.lang.c++:

    > On Sun, 05 Feb 2006 18:27:38 +0000, n2xssvv g02gfr12930 wrote:
    >
    > > Filipe Sousa wrote:
    > >>
    > >> Could someone explain to me why this operation is not what I was
    > >> expecting?
    > >>
    > >> int main()
    > >> {
    > >> int x = 2;
    > >> std::cout << x << " " << x++ << std::endl; return 0;
    > >> }

    > >
    > > The result is undefined for your example. This is because x++ could
    > > compiled to increment after the whole statement or immediately after use
    > > as in this case. In short if you want predictable behaviour when using
    > > operator ++ then the variable it is applied to should only appear once in
    > > the expression being evaluated.

    >
    > TB's reference to sequence points[1] sits better as a reply to this
    > remark because, while this is excellent advice for beginners, it is not
    > entirely true due to expressions like x++ || x++ which have, I think,
    > predictable behaviour (however daft they may be in practice).


    That still has to do with sequence points. The logical operators ||
    and && do provide sequence points, so the behavior is well defined.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Feb 5, 2006
    #7
  8. Filipe Sousa

    Jack Klein Guest

    On Sun, 05 Feb 2006 13:53:06 -0500, Kai-Uwe Bux <>
    wrote in comp.lang.c++:

    > TB wrote:
    >
    > > Filipe Sousa sade:
    > >> Hi!
    > >>
    > >> Could someone explain to me why this operation is not what I was
    > >> expecting?
    > >>
    > >> int main()
    > >> {
    > >> int x = 2;
    > >> std::cout << x << " " << x++ << std::endl;
    > >> return 0;
    > >> }
    > >>
    > >> main.cc: In function 'int main()':
    > >> warning: operation on 'x' may be undefined
    > >>
    > >> The result is
    > >> 3 2
    > >>
    > >> I would expect 2 2.
    > >>
    > >> Thanks
    > >> Filipe Sousa

    > >
    > > http://www.parashift.com/c -faq-lite/misc-technical-issues.html#faq-39.16
    > >

    >
    > I think, this is *not* a matter of sequence points. The expression is
    > equivalent to:
    >
    > operator<< (
    > operator<< (
    > operator<< (
    > operator<< ( std::cout, x ),
    > " "
    > ),
    > x++
    > ),
    > std::endl;
    > );
    >
    > and the various function calls provide sufficiently many sequence points.
    >
    > The results are implementation defined because the evaluation order of the
    > parameters passed in a function call is implementation defined.


    It really still is sequence points. There is no guarantee in the
    original expression, or in the expression as you have rewritten it,
    that any of the sequence points occurs in between the two accesses of
    'x'. The results are undefined for that reason.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Feb 5, 2006
    #8
  9. Filipe Sousa

    Kai-Uwe Bux Guest

    Jack Klein wrote:

    > On Sun, 05 Feb 2006 13:53:06 -0500, Kai-Uwe Bux <>
    > wrote in comp.lang.c++:
    >

    [snip]
    >> I think, this is *not* a matter of sequence points. The expression is
    >> equivalent to:
    >>
    >> operator<< (
    >> operator<< (
    >> operator<< (
    >> operator<< ( std::cout, x ),
    >> " "
    >> ),
    >> x++
    >> ),
    >> std::endl;
    >> );
    >>
    >> and the various function calls provide sufficiently many sequence points.
    >>
    >> The results are implementation defined because the evaluation order of
    >> the parameters passed in a function call is implementation defined.

    >
    > It really still is sequence points. There is no guarantee in the
    > original expression, or in the expression as you have rewritten it,
    > that any of the sequence points occurs in between the two accesses of
    > 'x'. The results are undefined for that reason.


    Thanks for the correction,

    I think, I see what you mean. Just to check my understanding: the following
    is implementation defined behavior, but not undefined


    int post_inc( int & x ) {
    int dummy = x;
    ++x;
    return( dummy );
    }

    operator<< (
    operator<< (
    operator<< (
    operator<< ( std::cout, x ),
    " "
    ),
    post_inc( x )
    ),
    std::endl;
    );

    The reason would be that in the evaluation of sub-expressions one of the
    calls operator<<( std::cout, x ) and post_inc( x ) comes first.
    Whichever comes first has a sequence point upon return, which separates the
    two accesses to x. The reason this does not apply to the original
    expression is that x++ is not a function call. Is that correct?


    Thanks again

    Kai-Uwe Bux
    Kai-Uwe Bux, Feb 6, 2006
    #9
  10. On Sun, 05 Feb 2006 17:48:12 -0600, Jack Klein wrote:

    > On Sun, 05 Feb 2006 19:23:40 +0000, Ben Bacarisse <>
    > wrote in comp.lang.c++:
    >
    >> On Sun, 05 Feb 2006 18:27:38 +0000, n2xssvv g02gfr12930 wrote:
    >>
    >> > In short if you want predictable behaviour when
    >> > using operator ++ then the variable it is applied to should only
    >> > appear once in the expression being evaluated.

    >>
    >> TB's reference to sequence points[1] sits better as a reply to this
    >> remark because, while this is excellent advice for beginners, it is not
    >> entirely true due to expressions like x++ || x++ which have, I think,
    >> predictable behaviour (however daft they may be in practice).

    >
    > That still has to do with sequence points. The logical operators || and
    > && do provide sequence points, so the behavior is well defined.


    I thought that is what I had said :/

    --
    Ben.
    Ben Bacarisse, Feb 6, 2006
    #10
  11. Filipe Sousa

    Guest

    Kai-Uwe Bux wrote:
    > I think, I see what you mean. Just to check my understanding: the following
    > is implementation defined behavior, but not undefined
    >
    >
    > int post_inc( int & x ) {
    > int dummy = x;
    > ++x;
    > return( dummy );
    > }
    >
    > operator<< (
    > operator<< (
    > operator<< (
    > operator<< ( std::cout, x ),
    > " "
    > ),
    > post_inc( x )
    > ),
    > std::endl;
    > );
    >
    > The reason would be that in the evaluation of sub-expressions one of the
    > calls operator<<( std::cout, x ) and post_inc( x ) comes first.
    > Whichever comes first has a sequence point upon return, which separates the
    > two accesses to x. The reason this does not apply to the original
    > expression is that x++ is not a function call. Is that correct?


    Yes, although an easier way to put this is to note that you surrounded
    every
    x++ by two sequence points, one entering and one leaving post_inc().
    Hence
    all changes of x must be separated by sequence points.

    Michiel Salters
    , Feb 6, 2006
    #11
  12. Filipe Sousa

    Kai-Uwe Bux Guest

    wrote:

    >
    > Kai-Uwe Bux wrote:
    >> I think, I see what you mean. Just to check my understanding: the
    >> following is implementation defined behavior, but not undefined
    >>
    >>
    >> int post_inc( int & x ) {
    >> int dummy = x;
    >> ++x;
    >> return( dummy );
    >> }
    >>
    >> operator<< (
    >> operator<< (
    >> operator<< (
    >> operator<< ( std::cout, x ),
    >> " "
    >> ),
    >> post_inc( x )
    >> ),
    >> std::endl;
    >> );
    >>
    >> The reason would be that in the evaluation of sub-expressions one of the
    >> calls operator<<( std::cout, x ) and post_inc( x ) comes first.
    >> Whichever comes first has a sequence point upon return, which separates
    >> the two accesses to x. The reason this does not apply to the original
    >> expression is that x++ is not a function call. Is that correct?

    >
    > Yes, although an easier way to put this is to note that you surrounded
    > every
    > x++ by two sequence points, one entering and one leaving post_inc().
    > Hence
    > all changes of x must be separated by sequence points.


    Now, I am confused again: if the post_inc() call "surrounds" x++ by two
    sequence points (forcing separation), then: why does operator<<( std::cout,
    x) not surround x in the same way (also forcing separation). I am asking
    because this is what I was thinking first.


    Thanks

    Kai-Uwe Bux
    Kai-Uwe Bux, Feb 6, 2006
    #12
  13. Filipe Sousa

    Guest

    Kai-Uwe Bux wrote:
    > wrote:
    > > Yes, although an easier way to put this is to note that you surrounded
    > > every
    > > x++ by two sequence points, one entering and one leaving post_inc().
    > > Hence
    > > all changes of x must be separated by sequence points.

    >
    > Now, I am confused again: if the post_inc() call "surrounds" x++ by two
    > sequence points (forcing separation), then: why does operator<<( std::cout,
    > x) not surround x in the same way (also forcing separation). I am asking
    > because this is what I was thinking first.


    Easy: post_inc() must start execution before x++ is executed, and
    cannot
    finish execution until x++ is executed (once). There are sequence
    points
    on "both sides of time". On the other hand, in the original example the

    only thing you know is that x++ must be called before operator<<.
    However,
    it can be done arbitrarily early. There is no sequence point that must
    be later
    than the first x++, but earlier than the second.

    In general, sequence point work in both ways: to keep things from
    starting
    too early, and from finishing too late. But you need two sequence
    points
    if you need both guarantees.

    HTH,
    Michiel Salters
    , Feb 6, 2006
    #13
    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. Ensoul Chee
    Replies:
    7
    Views:
    667
    Ensoul Chee
    Sep 9, 2003
  2. Pmb

    std::cout vs cout

    Pmb, Jun 2, 2004, in forum: C++
    Replies:
    2
    Views:
    4,389
    Leor Zolman
    Jun 2, 2004
  3. Stefan Ram

    Re: cout vs std::cout

    Stefan Ram, Sep 28, 2008, in forum: C++
    Replies:
    7
    Views:
    459
  4. saurabh29789

    Sending std::cout to std::cout !!

    saurabh29789, Jun 11, 2009, in forum: C++
    Replies:
    1
    Views:
    279
    Harald Finster
    Jun 11, 2009
  5. saurabh29789

    Sending std::cout to std::cout

    saurabh29789, Jun 11, 2009, in forum: C++
    Replies:
    2
    Views:
    333
    Rolf Magnus
    Jun 12, 2009
Loading...

Share This Page