Eine Überlastung Operator << und Rekursion
-
23-09-2019 - |
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?
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.