简体   繁体   中英

Strange outputs of mixed up std::cout

C++'s std::cout seems to be an interesting thing. I tried the following program on my C++ compiler today:

cout<<"!"<<"@"<<endl;
cout<<"!"<<cout<<"@"<<endl;
cout<<"!"<<(cout<<"@")<<endl;

And the outputs are rather curious:

!@
!0x601068@
@!0x601068

The first line is pedestrian; the second is understandable; however, the third line is beyond my knowledge. Could someone explain the output? Thank you guys all in advance!

Ziyao Wei

This line:

cout<<"!"<<(cout<<"@")<<endl;

It is first executing:

(cout << "@")

Note: It could have executed something else first, but the compiler optimized this sub-expression and found it could move this to the start of the statement without breaking any constraints.

The result of this expression is a stream (cout). So the resulting expression is:

cout<<"!"<< cout <<endl;

This results in:

@!<pointer>

The parenthes affect the order of evaluation here as in any other expression (<< is an operator). Because the expression has side-effects , those side-effects occur in the same order as the expression evaluation.

This third line illustrates the syntactic sugar that is the insertion operator.

Essentially the (cout<<"@") expression is evaluated first, resulting in the @ , which returns the stream cout itself.

Its only then that the ! first, followed by the expression is sent to cout .

Its equivalent to:

operator<<( operator<<( operator<<(cout,"!"), ( operator<<(cout,"@") ) ), endl);
                                                ^------------------^

The highlighted section is an expression which has to be evaluated before any functions are called.

My supposition -- the parentheses in the 3rd line make the cout<<"@" execute first, which puts the @ at the start of the line. Then the cout.operator<<("!") executes which puts the ! in place. And then the ostream that cout.operator<<("!") returns runs its operator<<() which is given the ostream that cout<<"@" returned, thus outputting the 0x601068 .

If you understand the second line, why does the third confuse you?

First of all, the expression in the parentheses is evaluated (but the order of evaluation is unspecified), thus @ is wrote on the standard output; such expression returns a reference to cout , as happens always with insertion operators, since otherwise they couldn't be chained.

Now that this part of the expression is evaluated, everything proceeds as normal: what is on the line is wrote from left to right: first the ! , then the value returned from the expression in the parentheses (ie the reference to cout and then the endl .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM