Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top