5

我尝试了以下代码:

#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;
}

当我编译并运行它时,它符合预期;一个无限循环。如果我删除cout朋友函数中的语句,则不会发生递归。为什么会这样?

4

2 回答 2

7

优化器确定您所有剩余的活动都没有效果并将其优化掉。是对是错是另外一回事。

尤其:

X x;

创建空对象“x”

cout << x;

调用:

return (os << obj);

这是附加空对象;编译器注意到“os”自上次调用以来没有增长,并且没有显示任何进一步的承诺(并且没有其他任何事情发生),因此它决定整个业务是多余的,并且可以在此时截断。

万一你打电话

    cout << "hehe";          // comment this and infinite loop is gone

有一些额外的活动,因此优化器不会删除以下调用。

我想如果你x用任何非空的东西进行初始化,或者执行任何非空的活动cout << "hehe";,你就会有同样的递归运行。

于 2010-03-01T11:06:04.503 回答
6

在这两种情况下(有和没有写“hehe”)Visual Studio 2005 都会给出以下警告:

warning C4717: 'operator<<' : recursive on all control paths, function will cause runtime stack overflow

在这两种情况下它都会编译并且在这两种情况下都会产生堆栈溢出。

但是,如果没有“呵呵”,堆栈溢出会更快发生。

于 2010-03-01T11:04:34.413 回答