cout, operator<<, sequence points

Discussion in 'C++' started by kalki70, Jul 23, 2007.

  1. kalki70

    kalki70 Guest

    Hello,

    I have a doubt about this operator, and I haven't found the answer in
    internet (yet).
    When calling the operator << several times in an expression, are all
    parameters evaluated first and then passed to cout::<<, or are being
    passed when they are evaluated ?
    An example to clarify my question :

    int foo()
    {
    cout << "calling foo";
    return 1;
    }

    ......
    cout << "i = " << foo() << endl;

    Should I see this:

    calling fooi = 1

    or

    i = calling foo1 ??

    Or is it undefined behaviour?

    So going to the original question.... is "i=" passed to cout::<< first
    and then foo() is evaluated and passed to cout::<<, or is foo()
    evaluated and just then "i = " and foo() are passed to cout::<< ?? Or
    undefined behaviour?

    Thanks in advance,

    Luis
    kalki70, Jul 23, 2007
    #1
    1. Advertising

  2. kalki70 wrote:
    > I have a doubt about this operator, and I haven't found the answer in
    > internet (yet).
    > When calling the operator << several times in an expression, are all
    > parameters evaluated first and then passed to cout::<<, or are being
    > passed when they are evaluated ? [...]


    The order of argument evaluation is _unspecified_ in the Standard.

    Even if you figure it out (by introducing side effects, or looking
    at the assembly), you should immediately forget about it because
    the order may (and most likely will) be different with a different
    compiler, different optimization setting of the same compiler or
    just because it's a holiday.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jul 23, 2007
    #2
    1. Advertising

  3. kalki70

    kalki70 Guest

    On Jul 23, 1:11 pm, "Victor Bazarov" <> wrote:
    > kalki70 wrote:
    > > I have a doubt about this operator, and I haven't found the answer in
    > > internet (yet).
    > > When calling the operator << several times in an expression, are all
    > > parameters evaluated first and then passed to cout::<<, or are being
    > > passed when they are evaluated ? [...]

    >
    > The order of argument evaluation is _unspecified_ in the Standard.
    >
    > Even if you figure it out (by introducing side effects, or looking
    > at the assembly), you should immediately forget about it because
    > the order may (and most likely will) be different with a different
    > compiler, different optimization setting of the same compiler or
    > just because it's a holiday.
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask



    Yes, but this situation is more complicated and it is not clear to me.
    It is very clear when I call a function with several parameters, like
    func(f(x), g(x));
    The order of evaluation of f(x) and g(x) is unspecified when calling
    func().
    But what happens when I can cout::<< several times like in my example?

    cout << "i = " << foo() << endl;

    Aren't these calls, 3 different independent calls to operator
    cout::<< , every one with only one parameter?? And if they are 3
    independent calls, is every parameter evaluated before calling
    cout::<< each time, or are all parameters evaluated first, and then
    all 3 calls to cout::<< are executed? How does this operator work?

    It is this sintax, calling the same operator several times in one
    expression which confuses me.

    Thanks again,

    Luis
    kalki70, Jul 23, 2007
    #3
  4. kalki70 wrote:
    > On Jul 23, 1:11 pm, "Victor Bazarov" <> wrote:
    >> kalki70 wrote:
    >>> I have a doubt about this operator, and I haven't found the answer
    >>> in internet (yet).
    >>> When calling the operator << several times in an expression, are all
    >>> parameters evaluated first and then passed to cout::<<, or are being
    >>> passed when they are evaluated ? [...]

    >>
    >> The order of argument evaluation is _unspecified_ in the Standard.
    >>
    >> Even if you figure it out (by introducing side effects, or looking
    >> at the assembly), you should immediately forget about it because
    >> the order may (and most likely will) be different with a different
    >> compiler, different optimization setting of the same compiler or
    >> just because it's a holiday.
    >>
    >> V
    >> --
    >> Please remove capital 'A's when replying by e-mail
    >> I do not respond to top-posted replies, please don't ask

    >
    >
    > Yes, but this situation is more complicated and it is not clear to me.
    > It is very clear when I call a function with several parameters, like
    > func(f(x), g(x));
    > The order of evaluation of f(x) and g(x) is unspecified when calling
    > func().
    > But what happens when I can cout::<< several times like in my example?
    >
    > cout << "i = " << foo() << endl;
    >
    > Aren't these calls, 3 different independent calls to operator
    > cout::<< , every one with only one parameter??


    No, it's three calls to different functions (all 'operator<<'), and
    each of them has _two_ arguments (it's after all a _binary_ operator).

    > And if they are 3
    > independent calls, is every parameter evaluated before calling
    > cout::<< each time, or are all parameters evaluated first, and then
    > all 3 calls to cout::<< are executed? How does this operator work?
    >
    > It is this sintax, calling the same operator several times in one
    > expression which confuses me.


    Don't worry. It confuses many, not just you. The expression is
    semantically equivalent to

    operator << (operator << (operator << (cout, "i = "), foo()), endl)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^ #1
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #2
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #3

    As you can see there are _at_least_ four arguments here that need
    to be evaluated before anything can proceed ('cout', '"i = "', 'foo()'
    and 'endl'). The order of their evaluation is what I am talking about
    -- it's unspecified. That means that the call to 'foo' can happen at
    any point before the return value of it needs to be passed to the
    operator<< call number 2. We know only one thing: the order of the
    calls to the operator<< happens according to the numbers I showed here.

    The order can be

    endl
    foo()
    "i = " // nothing really needs to be evaluated
    cout // nothing really needs to be evaluated
    operator << #1
    operator << #2
    operator << #2

    Or it can be

    cout // nothing really needs to be evaluated
    "i = " // nothing really needs to be evaluated
    operator << #1
    foo()
    operator << #2
    endl
    operator << #2

    Or it can be any other combination of things (with some specifics,
    like a call to foo() can never happen after 'operator << #2').

    There is nothing in the Standard that would make one more likely than
    another.

    Anything else is guesswork.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jul 23, 2007
    #4
  5. kalki70

    Jack Klein Guest

    On Mon, 23 Jul 2007 19:04:41 -0000, kalki70 <> wrote
    in comp.lang.c++:

    > On Jul 23, 1:11 pm, "Victor Bazarov" <> wrote:
    > > kalki70 wrote:
    > > > I have a doubt about this operator, and I haven't found the answer in
    > > > internet (yet).
    > > > When calling the operator << several times in an expression, are all
    > > > parameters evaluated first and then passed to cout::<<, or are being
    > > > passed when they are evaluated ? [...]

    > >
    > > The order of argument evaluation is _unspecified_ in the Standard.
    > >
    > > Even if you figure it out (by introducing side effects, or looking
    > > at the assembly), you should immediately forget about it because
    > > the order may (and most likely will) be different with a different
    > > compiler, different optimization setting of the same compiler or
    > > just because it's a holiday.
    > >
    > > V
    > > --
    > > Please remove capital 'A's when replying by e-mail
    > > I do not respond to top-posted replies, please don't ask

    >
    >
    > Yes, but this situation is more complicated and it is not clear to me.
    > It is very clear when I call a function with several parameters, like
    > func(f(x), g(x));
    > The order of evaluation of f(x) and g(x) is unspecified when calling
    > func().
    > But what happens when I can cout::<< several times like in my example?
    >
    > cout << "i = " << foo() << endl;
    >
    > Aren't these calls, 3 different independent calls to operator
    > cout::<< , every one with only one parameter?? And if they are 3
    > independent calls, is every parameter evaluated before calling
    > cout::<< each time, or are all parameters evaluated first, and then
    > all 3 calls to cout::<< are executed? How does this operator work?


    No, these are three calls to cout::eek:perator <<, each of which actually
    has two arguments, the first of which is the implicit reference to a
    stream. Furthermore, each call to cout::eek:perator << returns a
    reference to an output stream, which happens to be exactly the same
    reference that it was called with.

    That is the reason that you can chain stream insertion and deletion
    operators.

    The second << (for foo() ) is called on the stream object reference
    returned by the first << (for "i = " ). The third << (for endl) is
    called on the stream object reference returned by the second << (for
    foo() ).

    This ensures that the calls to cout::eek:perator << are made in the order
    written left-to-right, because each one needs the reference returned
    by the one to its left.

    > It is this sintax, calling the same operator several times in one
    > expression which confuses me.


    The order of calls to the insertion operator is fixed. The order of
    evaluation of the operands is not. The compiler might generate code
    to call foo() and store the result somewhere before it calls
    cout::eek:perator << for the string literal. But it must make that
    insertion call before it makes the insertion call for the value
    returned by foo().

    --
    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.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Jul 23, 2007
    #5
  6. kalki70

    kalki70 Guest

    Victor, Jack, I really appreciate your answers, now it is also clear
    to me.

    Thanks a lot,

    Luis
    kalki70, Jul 24, 2007
    #6
    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. abi

    man cout or info cout

    abi, Jun 27, 2003, in forum: C++
    Replies:
    2
    Views:
    1,634
  2. Pmb

    std::cout vs cout

    Pmb, Jun 2, 2004, in forum: C++
    Replies:
    2
    Views:
    4,391
    Leor Zolman
    Jun 2, 2004
  3. Replies:
    4
    Views:
    308
    Howard
    Sep 15, 2005
  4. ais523
    Replies:
    9
    Views:
    353
    Kaz Kylheku
    Feb 9, 2008
  5. Stefan Ram

    Re: cout vs std::cout

    Stefan Ram, Sep 28, 2008, in forum: C++
    Replies:
    7
    Views:
    460
Loading...

Share This Page