Sobrecarga << Operador e recursão
-
23-09-2019 - |
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?
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.