I tried the following code:
#include <iostream>
using std::cout;
using std::ostream;
class X
{
public:
friend ostream& operator<<(ostream &os, const X& obj)
{
cout << "hehe"; // comment this and infinite loop is gone
return (os << obj);
}
};
int main()
{
X x;
cout << x;
return 0;
}
When I compile & run this, it's as expected; an infinite loop. If I remove the cout
statement inside the friend function, the recursion doesn't happen. Why is it so?
We can overload the '>>' and '<<' operators to take input in a linked list and print the element in the linked list in C++. It has the ability to provide the operators with a special meaning for a data type, this ability is known as Operator Overloading.
You can redefine or overload the function of most built-in operators in C++. These operators can be overloaded globally or on a class-by-class basis. Overloaded operators are implemented as functions and can be member functions or global functions.
These operators cannot be overloaded because if we overload them it will make serious programming issues. For an example the sizeof operator returns the size of the object or datatype as an operand. This is evaluated by the compiler.
The stream insertion and stream extraction operators also can be overloaded to perform input and output for user-defined types like an object. Here, it is important to make operator overloading function a friend of the class because it would be called without creating an object.
Optimizer decides all your remaining activity has no effect and optimizes it away. Whether it's right or wrong is a different matter.
In particular:
X x;
creates empty object "x"
cout << x;
calls:
return (os << obj);
which is appending empty object; the compiler notices 'os' hasn't grown any since the last call and shows no promise doing so any further (and nothing else happens) so it decides the whole business is redundant and can be truncated at this point.
In case you call
cout << "hehe"; // comment this and infinite loop is gone
there is some extra activity so the optimizer doesn't remove the following call.
I guess if you initialized x
with anything non-empty, or performed any non-null activity other than cout << "hehe";
, you'd have recursion running just the same.
In both cases (with and without writing "hehe") Visual Studio 2005 gives the following warning:
warning C4717: 'operator<<' : recursive on all control paths, function will cause runtime stack overflow
In both cases it compiles and in both cases it gives a stack overflow.
However, without the "hehe" the stack overflow occurs a bit sooner.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With