How does cout's << operator work with regard to operator precedence? [duplicate]
Asked Answered
C

2

3

Possible Duplicate:
Unexpected order of evaluation (compiler bug?)

I couldn't predict the output for this program :

#include<iostream>
using namespace std;

int *p(int *a)
{
    (*a)++;
    return a;
}
int main()
{
    int i=0;

    cout<<i++<<" "<<(*p(&i))++<<" "<<i++<<" "<<i<<endl;
    return 0;
}

When compiled in vs2008, it outputs 3 2 0 4. Can anybody explain why it's not 0 2 3 4 ?

Note: It works great if there is no function call to p.

Thanks in advance!

Candent answered 2/1, 2012 at 19:12 Comment(1)
Yes, the behaviour is undefined. The question you should be asking yourself is why you would want to write such code. The answer is that you don't.Infanta
G
3

Undefined behaviour. Could do anything.

See this answer for a good explanation.

Glennaglennie answered 2/1, 2012 at 19:14 Comment(9)
So cout << x << y could print y and then x?!Burnedout
isn't it something depends on priority ! and why it works ok when I don't call "p" ?Candent
AtoMerZ: no, because that is not undefined. @Khaledvic: "Could do anything" means it can also "work" (or appear to).Countersubject
@Candent the order in which each thing between each << is undefined, but the order in which the operator<< calls occur, after everything between each << are all evaluated, is left to right.Nascent
What's the scenario behind the 3 2 0 4 output? I found no logical order in which compiler evaluates the four operands, first the 3rd one, then 2nd, then 1st and last the 4th operand! Is it some kind of lazy evaluating?Prettypretty
It's still unclear to me (even when I read the answer in link). What makes his case undefined and mine not undefined. if I had said cout << x << y << z could it print z x y?Burnedout
@AtoMerZ: Because your case isn't modifying any of the operands.Glennaglennie
That's right. But in cout << x << y << z couldn't z be evaluated before x and y? What if I had said cout << x++ << y++ << z++?Burnedout
@AtoMerZ: Ok, to be more specific; your case is not operating on the same variable multiple times with side effects. (Of course, if y and z are references to x, then your new example will be undefined.)Glennaglennie
W
0

The point isn't cout's precedence, but the ++ operator.
This operator's side effect can take place any time between two sequence points, which means anywhere in the statemenet, in this case. The exact order it happens is, as @oli-charlesworth says, undefined.
cout's precedence is left to right, so the leftmost is printed first. But the value of each number depends on the behavior of ++.

Wispy answered 2/1, 2012 at 19:37 Comment(2)
"cout's precedence is left to right" - this doesn't make any sense. cout is an object, not an operator. Also, sequence points are not really the problem here; the problem is that the sequence of evaluation of arguments to operator<< is unspecified.Glennaglennie
Indeed, the << operator's precedence is left to right, not cout. And I do think sequence points matter here (just as it does in "i++ + i++"), though maybe order of evaluation is more basic. But my main point was that it isn't (as someone mistakenly understood from your answer) order of precedence.Wispy

© 2022 - 2024 — McMap. All rights reserved.