1

Why does the following print out "World Hello!"?

From my understanding, according to operator precedence, this should be evaluated left from right. But instead it seems to be right to left to right. Why is this?

#include <iostream>

using namespace std;


char print() {
    cout << "World";
    return '!';
}

int main() {
    cout << "Hello " << print() << endl;
    return 0;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
xyz
  • 186
  • 1
  • 3
  • 19
  • 1
    Sorry, wrong link. Should have been [Order of evaluation of operands](http://stackoverflow.com/questions/7112282/order-of-evaluation-of-operands?lq=1) – Bo Persson Mar 26 '13 at 10:22
  • I apologize, I'm still new to this. I didn't know that topic is relevant to my problem. – xyz Mar 26 '13 at 10:22
  • 1
    Your understanding is wrong. The order is undefined, i.e. it can be left-to-right, right-to-left, or from the middle outwards zigzagging. – n. m. could be an AI Mar 26 '13 at 10:22
  • 2
    @Seb - No need to apologize, this is difficult. The operator precedence tells us the order the operators are applied, but not the order the parameters are evaluated. The compiler is allowed to evaluate those in advance, and in no particular order. – Bo Persson Mar 26 '13 at 10:29
  • @n.m. You mean unspecified. Using the word "undefined" in a different sense than The Standard's only causes confusion and nitpicking. – molbdnilo Mar 26 '13 at 10:32
  • Could it be releated to stream buffering ? – FredericS Mar 26 '13 at 10:38

4 Answers4

6

I do not think the standard gives any guarantee about the exact moment when print() is called with respect to the application of the << operator.

In your case, it looks like print() is called first, then cout << Hello is evaluated, and only then [result of the previous expression] << [result of print()] is evaluated.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
4

This becomes

operator<<
(
    operator<<
    (
        cout,
        "Hello"
    ),
    print()
)
.operator<<
(
    endl
);

The order of evalutation of arguments is unspecified, so there's nothing saying that the innermost operator<< has to be evaluated before print() in the call to the second-innermost operator<<.

Think about it like this: foo( f1(), f2() );. Which will be evaluated first, f1() or f2()? We don't know. We only know that both will be completed before foo() runs.

The left-to-right precedence means it ends up paired up the way I wrote it.

Much later edit: Slight technical error. The call taking endl will actually be a member version. Doesn't make any difference to anything else though.

Community
  • 1
  • 1
BoBTFish
  • 19,167
  • 3
  • 49
  • 76
2

this should be evaluated left from right.

It does. You can see it from the ! at the very end. But, the final string is printed by cout after the operators have been evaluated. But, during operator evaluation, you are printing World. The Hello! is then printed afterwards. Hence, you get WorldHello!.

As others write, even if it is the result you get (and I could verify it), it might even be undefined behavior with respect to the calling order, since the order of evaluation is unspecified.

@Bo gave a very good link which points to the C++ standard:

§5.2.2.8 - [...] The order of evaluation of function arguments is unspecified. [...]
Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
1

The order is undefined. Look at Order of evaluation.

cout << i << i++; // Undefined behavior
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kalvis
  • 560
  • 2
  • 10
  • 1
    The order of evaluation is *unspecified* which is technically slightly different from *undefined*. And also different from your example. – Bo Persson Mar 26 '13 at 10:24