Whether intentionally or by accident, you have <<
at the end of the first output line, where you probably meant ;
. So you essentially have
cout << "2+3 = "; // this, of course, prints "2+3 = "
cout << cout; // this prints "1"
cout << 2 + 3; // this prints "5"
cout << endl; // this finishes the line
So the question boils down to this: why does cout << cout;
print "1"
?
This turns out to be, perhaps surprisingly, subtle. std::cout
, via its base class std::basic_ios
, provides a certain type conversion operator that is intended to be used in boolean context, as in
while (cout) { PrintSomething(cout); }
This is a pretty poor example, as it's difficult to get output to fail - but std::basic_ios
is actually a base class for both input and output streams, and for input it makes much more sense:
int value;
while (cin >> value) { DoSomethingWith(value); }
(gets out of the loop at end of stream, or when stream characters do not form a valid integer).
Now, the exact definition of this conversion operator has changed between C++03 and C++11 versions of the standard. In older versions, it was operator void*() const;
(typically implemented as return fail() ? NULL : this;
), while in newer it's explicit operator bool() const;
(typically implemented simply as return !fail();
). Both declarations work fine in a boolean context, but behave differently when (mis)used outside of such context.
In particular, under C++03 rules, cout << cout
would be interpreted as cout << cout.operator void*()
and print some address. Under C++11 rules, cout << cout
should not compile at all, as the operator is declared explicit
and thus cannot participate in implicit conversions. That was in fact the primary motivation for the change - preventing nonsensical code from compiling. A compiler that conforms to either standard would not produce a program that prints "1"
.
Apparently, certain C++ implementations allow mixing and matching the compiler and the library in such a way that produces non-conforming outcome (quoting @StephanLechner: "I found a setting in xcode which produces 1, and another setting that yields an address: Language dialect c++98 combined with "Standard library libc++ (LLVM standard library with c++11 support)" yields 1, whereas c++98 combined with libstdc (gnu c++ standard library) yields an address;"). You can have a C++03-style compiler that doesn't understand explicit
conversion operators (which are new in C++11) combined with a C++11-style library that defines the conversion as operator bool()
. With such a mix, it becomes possible for cout << cout
to be interpreted as cout << cout.operator bool()
, which in turn is simply cout << true
and prints "1"
.