Question

I know cout and printf have buffer today, and it is said that the buffer is some like a stack and get the output of cout and printf from right to left, then put them out(to the console or file)from top to bottem. Like this,

a = 1; b = 2; c = 3;
cout<<a<<b<<c<<endl;
buffer:|3|2|1|<-   (take “<-” as a poniter)

output:|3|2|<-     (output 1)
        |3|<-       (output 2)
        |<-         (output 3)

Then I write a code below,

#include <iostream> 
using namespace std; 
int c = 6;
int f() 
{   
    c+=1; 
    return c; 
} 

int main() 
{ 
     int i = 0; 
     cout <<"i="<<i<<" i++="<<i++<<" i--="<<i--<<endl; 
     i = 0;
     printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );

     cout<<f()<<" "<<f()<<" "<<f()<<endl; 
     c = 6;
     printf("%d %d %d\n" , f() , f() ,f() );
     system("pause");
     return 0; 
} 

Under VS2005, the output is

i=0 i++=-1 i--=0
i=0 i++=-1 i--=0
9 8 7
9 8 7

Under g++( (GCC) 3.4.2 (mingw-special)), the output is,

i=0 i++=0 i--=1
i=0 i++=-1 i--=0
9 8 7
9 8 7

It seems that the buffer is like a stack. However, I read C++ Primer Plus today, and it is said that the cout work from left to right, every time return an object(cout), so "That’s the feature that lets you concatenate output by using insertion". But the from left to right way can not explain cout< output 9 8 7 Now I'm confused about how cout's buffer work, can somebody help me?

Was it helpful?

Solution

This is not a bug, nor is it anything to do with output buffering.

The order of execution of the i-- and i++ operations is not defined when they're invoked more than once as parameters to the same function call.

To elaborate (and possibly correct) Iraimbilanja's mention of "sequence points", the cout version is equivalent to:

(((cout << a) << b) << c)

Effectively, it's actually three separate function calls, each of whose parameters are evaluated in order, even though it's written like a single statement.

The << operator is really ostream& operator<<(ostream& os, int), so another way of writing this is:

operator<< ( operator<< ( operator<< ( cout, a ), b ), c )

Since for the outer call it's not (AFAIK) defined which order the two parameters are evaluated, it's perfectly possible for the right-hand "c" parameter (or in your case "i--") to happen before the left hand parameter is evaluated.

OTHER TIPS

The output of:

printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );

is unspecified. This is a common pitfall of C++: argument evaluation order is unspecified.

Not so with the cout case: it uses chained calls (sequence points), not arguments to a single function, so evaluation order is well defined from left to right.

Edit: David Thornley points out that the behavior of the above code is in fact undefined.

if possible try updating to gcc >= 4. i just ran this on 4.0.1 and it executes just dandy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top