A correção do código que você escreve nunca deve depender de uma otimização. Ele deve gerar o resultado correto quando executado na "máquina virtual" C ++ que eles usam na especificação.
No entanto, o que você fala é mais um tipo de pergunta sobre eficiência. Seu código funciona melhor se otimizado com um compilador de otimização de RVO. Tudo bem, por todos os motivos apontados nas outras respostas.
No entanto, se você precisar dessa otimização (como se o construtor de cópias realmente causasse falha no seu código), agora você está nos caprichos do compilador.
Eu acho que o melhor exemplo disso em minha própria prática é a otimização de chamada de cauda:
int sillyAdd(int a, int b)
{
if (b == 0)
return a;
return sillyAdd(a + 1, b - 1);
}
É um exemplo bobo, mas mostra uma chamada de cauda, onde uma função é chamada recursivamente no final de uma função. A máquina virtual C ++ mostrará que esse código funciona corretamente, embora eu possa causar um pouco de confusão sobre o motivo de eu ter me preocupado em escrever essa rotina de adição em primeiro lugar. No entanto, nas implementações práticas do C ++, temos uma pilha e esse espaço é limitado. Se executada de forma pedântica, essa função teria que empurrar pelo menos b + 1
quadros de pilha para a pilha, como faz sua adição. Se eu quiser calcular sillyAdd(5, 7)
, isso não é grande coisa. Se eu quiser calcular sillyAdd(0, 1000000000)
, posso ter um problema real de causar um StackOverflow (e não o bom ).
No entanto, podemos ver que, quando alcançamos a última linha de retorno, realmente terminamos com tudo no quadro de pilha atual. Nós realmente não precisamos mantê-lo por perto. A otimização da chamada de cauda permite "reutilizar" o quadro de pilha existente para a próxima função. Dessa forma, precisamos apenas de 1 quadro de pilha, em vez de b+1
. (Ainda precisamos fazer todas essas adições e subtrações tolas, mas elas não ocupam mais espaço.) Com efeito, a otimização transforma o código em:
int sillyAdd(int a, int b)
{
begin:
if (b == 0)
return a;
// return sillyAdd(a + 1, b - 1);
a = a + 1;
b = b - 1;
goto begin;
}
Em alguns idiomas, a otimização da chamada de cauda é explicitamente exigida pela especificação. C ++ não é um desses. Não posso confiar nos compiladores C ++ para reconhecer esta oportunidade de otimização de chamada final, a menos que eu vá caso a caso. Com a minha versão do Visual Studio, a versão de lançamento faz a otimização de chamada de cauda, mas a versão de depuração não (por design).
Assim, seria ruim para mim depender de poder calcular sillyAdd(0, 1000000000)
.