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,030
  • 21
  • 100
  • 124
xyz
  • 186
  • 1
  • 3
  • 19

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
  • 249,845
  • 40
  • 466
  • 467
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
  • 18,486
  • 3
  • 53
  • 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
  • 35,119
  • 7
  • 92
  • 115
1

The order is undefined. Look at Order of evaluation.

cout << i << i++; // Undefined behavior
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
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