Frage

Ich habe versucht, den folgenden 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;
}

Wenn ich kompilieren und diese ausführen, wird es wie erwartet; eine Endlosschleife. Wenn ich die cout Anweisung innerhalb der Friend-Funktion entfernen, wird die Rekursion nicht passieren. Warum ist es so?

War es hilfreich?

Lösung

Optimizer entscheidet, alle Ihre verbleibende Aktivität hat keine Wirkung und optimiert sie weg. Ob es richtig oder falsch ist eine andere Sache.

Im Einzelnen:

X x;

erzeugt leeres Objekt "x"

cout << x;

Anrufe:

return (os << obj);

, die leer Objekt anhängt; Die ‚os‘ Compiler bemerkt haben jeder seit dem letzten Aufruf nicht gewachsen und zeigt keine so jeden weiteren Versprechen zu tun (und es passiert nichts anderes), so dass es das ganze Geschäft ist überflüssig entscheidet und kann an dieser Stelle abgeschnitten.

Falls Sie rufen

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

gibt es einige zusätzliche Aktivität so der Optimierer nicht den folgenden Aufruf nicht entfernen.

Ich denke, wenn man x mit irgendetwas nicht leer initialisiert, oder durchgeführt werden Nicht-Null-Aktivität außer cout << "hehe";, Sie Rekursion laufen gerade das gleiche haben würden.

Andere Tipps

In beiden Fällen (mit und ohne das Schreiben "hehe") Visual Studio 2005 gibt die folgende Warnung:

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

In beiden Fällen ist es kompiliert und in beiden Fällen gibt es einen Stapelüberlauf.

Doch ohne die „hehe“ der Stack-Überlauf tritt ein wenig früher.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top