weird behavior of algbraic evaluation in concatenated operators

Discussion in 'C++' started by dejan budimir, Jul 2, 2004.

  1. hi there!

    #include <iostream>
    using namespace std;

    void main(){

    int i=0,
    j=10;

    //Case one (the 'common' case):
    cout<< "i == " << i << endl
    << "j == " << j << endl;

    //Case two (the 'oddity'):
    //Should print 1 and 11 (but will not evaluate the former expression
    // before the latter, although it is printing in the correct order.
    cout<< "(i+=1) == " <<(i+=1)<< endl
    << "(j+=i) == " <<(j+=i)<< endl;
    }

    The ostream's operator<<() method is defined as to be passed only two
    arguments a time, one of which must be the class, which is being
    returned to allow concatenation.

    (cout<<expr1)<<expr2;

    But it seems as if the whole set of expressions is being evaluated,
    _before_ becoming the arguments of the operator methods and, in
    addition, is being evaluated from the right to the left (from the
    stack?).

    Is this a microsoft-specific way of dealing with concatenation?

    Havv ei got zee opchions wronk?
    dejan budimir, Jul 2, 2004
    #1
    1. Advertising

  2. dejan budimir

    Rolf Magnus Guest

    dejan budimir wrote:

    > hi there!
    >
    > #include <iostream>
    > using namespace std;
    >
    > void main(){


    main() must return int.

    >
    > int i=0,
    > j=10;
    >
    > //Case one (the 'common' case):
    > cout<< "i == " << i << endl
    > << "j == " << j << endl;
    >
    > //Case two (the 'oddity'):
    > //Should print 1 and 11 (but will not evaluate the former expression
    > // before the latter, although it is printing in the correct order.
    > cout<< "(i+=1) == " <<(i+=1)<< endl
    > << "(j+=i) == " <<(j+=i)<< endl;


    This invokes undefined behaviour because both i and j are modified twice
    without a sequence point in between. In theory, anything can happen.

    > }
    >
    > The ostream's operator<<() method is defined as to be passed only two
    > arguments a time, one of which must be the class, which is being
    > returned to allow concatenation.
    >
    > (cout<<expr1)<<expr2;
    >
    > But it seems as if the whole set of expressions is being evaluated,
    > _before_ becoming the arguments of the operator methods and, in
    > addition, is being evaluated from the right to the left (from the
    > stack?).


    Probably, but the C++ standard doesn't state any order of evaluation.

    > Is this a microsoft-specific way of dealing with concatenation?
    >
    > Havv ei got zee opchions wronk?


    --
    "Time flies like an arrow. Fruit flies like a banana."
    - Groucho Marx
    Rolf Magnus, Jul 2, 2004
    #2
    1. Advertising

  3. thanks! that really was fast.
    would be great to know what it actually is that "goes wrong", though.
    but, since i'll have to learn assembly anyway, i guess it's just a
    matter of banana.

    have a nice one!
    dejan budimir, Jul 2, 2004
    #3
  4. dejan budimir wrote:
    >
    > thanks! that really was fast.
    > would be great to know what it actually is that "goes wrong", though.


    What "goes wrong": The way you wrote your program.
    The C++ language simply does not define what should happen in this case.

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Jul 2, 2004
    #4
  5. Karl Heinz Buchegger wrote:

    > dejan budimir wrote:
    > >
    > > thanks! that really was fast.
    > > would be great to know what it actually is that "goes wrong", though.

    >
    > What "goes wrong": The way you wrote your program.
    > The C++ language simply does not define what should happen in this case.
    >
    >

    yes, thank you.
    dejan budimir, Jul 2, 2004
    #5
  6. dejan budimir

    Old Wolf Guest

    Rolf Magnus <> wrote:
    > dejan budimir wrote:
    >
    > > //Case two (the 'oddity'):
    > > //Should print 1 and 11 (but will not evaluate the former expression
    > > // before the latter, although it is printing in the correct order.
    > > cout<< "(i+=1) == " <<(i+=1)<< endl
    > > << "(j+=i) == " <<(j+=i)<< endl;

    >
    > This invokes undefined behaviour because both i and j are modified twice
    > without a sequence point in between. In theory, anything can happen.


    i and j are both only modified once, in this statement.
    The UB is because i is read for a purpose other than to determine
    its new value.
    Old Wolf, Jul 3, 2004
    #6
  7. dejan budimir

    Rolf Magnus Guest

    Old Wolf wrote:

    > Rolf Magnus <> wrote:
    >> dejan budimir wrote:
    >>
    >> > //Case two (the 'oddity'):
    >> > //Should print 1 and 11 (but will not evaluate the former
    >> > expression // before the latter, although it is printing in the
    >> > correct order.
    >> > cout<< "(i+=1) == " <<(i+=1)<< endl
    >> > << "(j+=i) == " <<(j+=i)<< endl;

    >>
    >> This invokes undefined behaviour because both i and j are modified
    >> twice without a sequence point in between. In theory, anything can
    >> happen.

    >
    > i and j are both only modified once, in this statement.


    Oops. You're right of course.

    > The UB is because i is read for a purpose other than to determine
    > its new value.


    And that's right, too. Sorry for the confusion.
    Rolf Magnus, Jul 4, 2004
    #7
    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. Prateek R Karandikar
    Replies:
    11
    Views:
    586
  2. Ilias Lazaridis
    Replies:
    2
    Views:
    390
    Ilias Lazaridis
    Apr 24, 2005
  3. Ilias Lazaridis
    Replies:
    74
    Views:
    751
    Ilias Lazaridis
    Apr 4, 2005
  4. Ilias Lazaridis
    Replies:
    18
    Views:
    332
    Bill Guindon
    Apr 9, 2005
  5. Roy Smith
    Replies:
    6
    Views:
    159
    Chris Angelico
    Dec 3, 2012
Loading...

Share This Page