开发者

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<<"!"<<"@"<&开发者_开发百科lt;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 (i.e. the reference to cout and then the endl.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜