Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading << operator and recursion

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?

like image 480
legends2k Avatar asked Mar 01 '10 10:03

legends2k


People also ask

Can we overload << operator?

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.

Can we overload << operator in C++?

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.

Why are << and >> operators Cannot be overloaded using member 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.

Can stream operators << and >> can be overloaded?

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.


2 Answers

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.

like image 61
SF. Avatar answered Sep 28 '22 14:09

SF.


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.

like image 27
Patrick Avatar answered Sep 28 '22 16:09

Patrick