3

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?

Darien Pardinas
  • 5,910
  • 1
  • 41
  • 48

2 Answers2

8

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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
2

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.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • Done! However I'm still not clear why `Expr2` is being evaluated before `Expr1`. I have tried GCC and MSVC – Darien Pardinas Jan 22 '15 at 01:21
  • @DarienPardinas it's because they want to, and they're allowed to. You, as a programmer, are not to assume which will be evaluated first. And if you want that control, you can put them on separate lines. Good luck! – Drew Dormann Jan 22 '15 at 01:23
  • @DarienPardinas Don't confused *observed* behavior with *specified* behavior or *defined* behavior. They're sometimes different things. When in doubt peel back the standard text and see where it takes you. – WhozCraig Jan 22 '15 at 01:26
  • Thanks! Anyway, that was one of the practice questions of the C++ Certified Associate Programmer and the right answer according to them is `21` even when that output should be undefined. – Darien Pardinas Jan 22 '15 at 01:27
  • 2
    @DarienPardinas Wow! Someone should have a chat with them, no? Can you share a link? – Drew Dormann Jan 22 '15 at 01:28
  • http://education.cppinstitute.org/ Chapter 6 Question 7. You need to register (it's free) to see it with your own eyes. – Darien Pardinas Jan 22 '15 at 01:33
  • @DarienPardinas their stock photos use differing gaussian blurs. That's the first red flag. – Drew Dormann Jan 22 '15 at 01:36
  • @DrewDormann What yo you mean with that? That is not worth looking at this certification? – Darien Pardinas Jan 22 '15 at 04:58