3
votes

Look at this simple class:

class A {
    int *val;
public:
    A() { val = new int; *val = 0; }
    int get() { return ++(*val); }
};

Why when I run this code it prints 21:

int main() {
    A a, b = a;
    cout << a.get() << b.get();
    return 0;
}

But if I run it like this it prints 12 which is what I was expecting:

int main() {
    A a, b = a;
    cout << a.get();
    cout << b.get();
    return 0;
}

What am I missing here? Operator precedence? FYI, this is a C++ test problem, not a production code.

EDIT: Does it means that when I have cout << (Expr1) << (Expr2) then Expr1 and Expr2 are evaluated before the output of Expr1 is printed?

2
This is about associativity, not precedence. There is only one operator, so the question of precedence cannot arise. - user207421
This is not about associativity. This is about order of evaluation of sub-expressions. - T.C.
@EJP No, it's not. It's generally unspecified. - T.C.
C++11 (draft N3337) dcl.fct.default: The order of evaluation of function arguments is unspecified. - legends2k

2 Answers

8
votes

Operator precedence does not dictate the order of evaluation of intermediate results. I.e. it does not dictate the order of evaluation of sub-expressions in the entire expression.

Expression statement

cout << a.get() << b.get();

can be executed by the compiler as

int tmp_a = a.get();
int tmp_b = b.get();
cout << tmp_a;
cout << tmp_b;

or as

int tmp_b = b.get();
int tmp_a = a.get();
cout << tmp_a;
cout << tmp_b;

In this case operator precedence and associativity for operator << guarantees that tmp_a is sent to output before tmp_b. But it does not guarantee that tmp_a is evaluated before tmp_b.

2
votes

This line:

cout << a.get() << b.get();

does not specify whether a.get() or b.get() is evaluated first.

Since a and b share the same val pointer, the order of those operations affect the output.

(Edit)

Does it means that when I have cout << (Expr1) << (Expr2) then Expr1 and Expr2 are evaluated before the output of Expr1 is printed?

That is also not specified.