Sovraccarico << dell'operatore e ricorsione
-
23-09-2019 - |
Domanda
Ho provato il seguente codice:
#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;
}
Quando compilo & Run questo, è come previsto; un ciclo infinito. Se rimuovo la dichiarazione cout
all'interno della funzione amico, la ricorsione non accade. Perché è così?
Soluzione
Optimizer decide tutte le attività rimanente ha alcun effetto e ottimizza via. Se è giusto o sbagliato è una questione diversa.
In particolare:
X x;
crea oggetto vuoto "x"
cout << x;
chiamate:
return (os << obj);
che è aggiungendo oggetto vuoto; gli avvisi del compilatore 'os' non è cresciuto alcun dopo l'ultima chiamata e non mostra la promessa di farlo ogni ulteriore (e niente altro succede) in modo che decide tutta la faccenda è ridondante e può essere troncato a questo punto.
Nel caso in cui si chiama
cout << "hehe"; // comment this and infinite loop is gone
c'è qualche attività in più in modo che l'ottimizzatore non rimuove la seguente chiamata.
Credo che se è stata inizializzata x
con qualsiasi cosa non vuota, o di qualsiasi attività svolta non nullo diverso cout << "hehe";
, si avrebbe la ricorsione in esecuzione lo stesso.
Altri suggerimenti
In entrambi i casi (con e senza scrivere "hehe") Visual Studio 2005 dà il seguente avviso:
warning C4717: 'operator<<' : recursive on all control paths, function will cause runtime stack overflow
In entrambi i casi si compila e in entrambi i casi si dà un overflow dello stack.
Tuttavia, senza "hehe" l'overflow di stack si verifica un po 'prima.