Pergunta

Eu tentei o seguinte código:

#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 eu compilar e executar isso, é o esperado; um loop infinito. Se eu remover o cout Declaração dentro da função do amigo, a recursão não acontece. Por que é tão?

Foi útil?

Solução

O Otimizer decide que toda a sua atividade restante não tem efeito e o otimiza. Se está certo ou errado, é uma questão diferente.

Em particular:

X x;

cria objeto vazio "x"

cout << x;

chamadas:

return (os << obj);

que está anexando objeto vazio; O 'OS' do compilador não cresceu desde a última chamada e não mostra nenhuma promessa fazê -lo mais (e nada mais acontece), por isso decide que todo o negócio é redundante e pode ser truncado neste momento.

Caso você ligue

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

Há alguma atividade extra para que o otimizador não remova a chamada a seguir.

Eu acho que se você inicializou x com qualquer coisa não vazia, ou realizou qualquer atividade não nula que não seja cout << "hehe";, você teria recursão funcionando da mesma forma.

Outras dicas

Nos dois casos (com e sem escrever "hehe") o Visual Studio 2005 dá o seguinte aviso:

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

Nos dois casos, ele compila e em ambos os casos fornece um estouro de pilha.

No entanto, sem o "hehe", o transbordamento da pilha ocorre um pouco mais cedo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top