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 the following code, does it print 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.

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

7
  • 4
    This is about associativity, not precedence. There is only one operator, so the question of precedence cannot arise. Commented Jan 22, 2015 at 1:07
  • 3
    This is not about associativity. This is about order of evaluation of sub-expressions. Commented Jan 22, 2015 at 1:08
  • 1
    @EJP No, it's not. It's generally unspecified. Commented Jan 22, 2015 at 1:09
  • 1
    stackoverflow.com/questions/5473107/… Commented Jan 22, 2015 at 1:14
  • 4
    C++11 (draft N3337) dcl.fct.default: The order of evaluation of function arguments is unspecified. Commented Jan 22, 2015 at 1:14

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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.

8 Comments

Done! However I'm still not clear why Expr2 is being evaluated before Expr1. I have tried GCC and MSVC
@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!
@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.
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.
@DarienPardinas Wow! Someone should have a chat with them, no? Can you share a link?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.