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ì?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top