O que é cópia elision? O que é (nomeado) otimização de valor de retorno? O que eles implicam?
Em que situações eles podem ocorrer? O que são limitações?
- Se você foi referenciado a esta pergunta, provavelmente está procurando a introdução .
- Para uma visão geral técnica, consulte a referência padrão .
- Veja casos comuns aqui .
c++
optimization
c++-faq
return-value-optimization
copy-elision
Luchian Grigore
fonte
fonte
Respostas:
Introdução
Para uma visão geral técnica - pule para esta resposta .
Para casos comuns em que a cópia é eliminada - pule para esta resposta .
A cópia elision é uma otimização implementada pela maioria dos compiladores para evitar cópias extras (potencialmente caras) em determinadas situações. Torna possível o retorno por valor ou passagem por valor na prática (aplicam-se restrições).
É a única forma de otimização que elimina (ha!) A regra como se - a cópia elision pode ser aplicada mesmo que copiar / mover o objeto tenha efeitos colaterais .
O exemplo a seguir, retirado da Wikipedia :
Dependendo do compilador e das configurações, as seguintes saídas são todas válidas :
Isso também significa que menos objetos podem ser criados; portanto, você também não pode contar com um número específico de destruidores sendo chamados. Você não deve ter lógica crítica dentro de copy / move-constructors ou destructors, pois não pode confiar neles.
Se uma chamada para um construtor de copiar ou mover for elidida, esse construtor ainda deve existir e deve estar acessível. Isso garante que a cópia elision não permita copiar objetos que normalmente não são copiáveis, por exemplo, porque eles têm um construtor de copiar / mover privado ou excluído.
C ++ 17 : A partir do C ++ 17, o Copy Elision é garantido quando um objeto é retornado diretamente:
fonte
Referência padrão
Para uma visão e introdução menos técnicas - pule para esta resposta .
Para casos comuns em que a cópia é eliminada - pule para esta resposta .
A cópia elision é definida no padrão em:
12.8 Copiando e movendo objetos de classe [class.copy]
Como
O exemplo dado é:
e explicou:
fonte
Formas comuns de cópia elision
Para uma visão geral técnica - pule para esta resposta .
Para uma visão e introdução menos técnicas - pule para esta resposta .
(Nomeado) A otimização do valor de retorno é uma forma comum de remoção de cópia. Refere-se à situação em que um objeto retornado por valor de um método tem sua cópia exagerada. O exemplo estabelecido no padrão ilustra a otimização do valor de retorno nomeado , uma vez que o objeto é nomeado.
A otimização do valor de retorno regular ocorre quando um temporário é retornado:
Outros locais comuns onde ocorre a remoção de cópias é quando um valor temporário é passado por valor :
ou quando um exceção é lançada e capturada por valor :
As limitações comuns da remoção de cópias são:
A maioria dos compiladores de nível comercial suporta cópia elision e (N) RVO (dependendo das configurações de otimização).
fonte
Copy elision é uma técnica de otimização de compilador que elimina a cópia / movimentação desnecessária de objetos.
Nas seguintes circunstâncias, um compilador pode omitir operações de copiar / mover e, portanto, não chamar o construtor associado:
Mesmo quando a elisão da cópia ocorre e o copiador / movedor-construtor não é chamado, ele deve estar presente e acessível (como se não houvesse otimização), caso contrário, o programa não está formado.
Você deve permitir a remoção dessa cópia apenas em locais onde não afetará o comportamento observável do seu software. A cópia elision é a única forma de otimização permitida a ter (ou seja, elide) efeitos colaterais observáveis. Exemplo:
O GCC oferece a
-fno-elide-constructors
opção de desativar a cópia elision. Se você deseja evitar possíveis elisiones de cópia, use-fno-elide-constructors
.Agora, quase todos os compiladores fornecem cópia elision quando a otimização está ativada (e se nenhuma outra opção estiver configurada para desativá-la).
Conclusão
Com cada cópia eliminada, uma construção e uma destruição correspondente da cópia são omitidas, economizando tempo de CPU e um objeto não é criado, economizando espaço no quadro da pilha.
fonte
ABC obj2(xyz123());
é NRVO ou RVO? é não ficar temporária variável / object mesmo queABC xyz = "Stack Overflow";//RVO