From this question & the answers – What is the correct answer for cout << c++ << c;?
I get that
std::cout<<c++<<c;
is evaluated as:
std::operator<<(std::operator<<(std::cout, c++), c);
so the undefined behavior comes from the fact that either of the two parameters could be evaluated first. So far so good.
But why std::operator <<? Why isn’t std::ostream::operator << called? And if it is, wouldn’t it translate to
(ofstream::operator<<(c++)) << c;
|
returns ofstream&
What’s the difference between this and method chaining:
struct A
{
A& foo();
void goo();
};
//...
A a;
a.foo().goo();
?
std::ostreamprovidesoperator<<as overloaded member operators, but other headers (e.g.<string>) provide free operators; so whether<<is a member operator or a free function depends on the RHS type.However, it doesn’t matter either way. Let’s rename
<<asfooandcoutasbar:In both cases behaviour is undefined because there is no requirement on the implementation to evaluate the arguments to either call to
fooin any particular order. The important consideration is that per Annex C, a chained method call does not constitute more than one full-expression; if the compiler seesit is free to apply CSE and reordering to the arguments to
barand tobaz; indeed examination of side effects may show that the arguments tobazare evaluated before those tobar.My compiler (gcc 4.1.2) generates a program which prints
bye\nhello\n.