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、または 以外のnull以外のアクティビティcout << "hehe";を実行した場合、再帰がまったく同じように実行されると思います。

于 2010-03-01T11:06:04.503 に答える
6

Visual Studio 2005 では、どちらの場合も ("hehe" と書く場合と書かない場合)、次の警告が表示されます。

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

どちらの場合もコンパイルされ、どちらの場合もスタック オーバーフローが発生します。

ただし、「hehe」がないと、スタック オーバーフローが少し早く発生します。

于 2010-03-01T11:04:34.413 に答える