C++ : Copy-elision y Return Value Optimization (NRVO / RVO)
Channel: Profesor Retroman
Date: 2019-03-16

Analizamos el funcionamiento del compilador a la hora de construir objetos de distintas formas, y cómo realiza las optimizaciones de #copy-elision (Evitación de copias) en casos oportunos. Utilizamos la herramienta cppinsights.io para entender mejor el proceso y ver también la optimización del valor de retorno (#return-value-optimization). 

Contenidos detallados:
- Vemos un nuevo ejemplo de GameObjects y Sprites con operadores salida definidos
- Observamos qué sucede cuando creamos un #GameObject como copia de otro
- Vemos que el operador asignación no es llamado en una definición de objeto, porque aún no está creado. Se llama en su lugar al constructor de copia.
- Con la ayuda de cppinsights.io entendemos mejor las definiciones de objetos y por qué no se llama al operador asignación.
- Llamamos al operador asignación utilizando 2 objetos ya construidos para asegurarnos de que no se llama al constructor de copia.
- Entendemos el proceso interno que sucede en nuestro #operator= que utiliza #copy&swap con una copia temporal pasada como parámetro
- Probamos a utilizar una función de creación de objetos (similar a un patrón fábrica, pero simplificado)
- Estudiamos posibles versiones de nuestra función de creación de objetos
 -- Creación directa de un objeto temporal que es devuelto
 -- Paso de objeto por referencia que es rellenado
 -- Uso de un único objeto global global/estático, que es creado una vez para devolver copias en cada llamada
- Analizamos posibles ventajas e inconvenientes teóricas de cada opción antes de probarlas
- Probamos cada una de las opciones y analizamos los resultados reales respecto a nuestra idea teórica de los mismos
- Entendemos las copias que se crean en cada caso y porqué sucede.
- Utilizamos cppinsights.io para entender el funcionamiento real de nuestro GameObject estático. Utiliza internamente un espacio de memoria estático reservado con placement new y un if que comprueba constantemente si el objeto ya ha sido previamente inicializado o no.
- Analizamos la optimización de valor de retorno, #return-value-optimization o #named-return-value-optimization.
- Explicamos el detalle de la creación de variables #NRVO / #RVO en los distintos #stack-frame de las funciones y cómo lo hace para evitar tener que crear copias innecesarias
- Analizamos los detalles que necesita el compilador para poder realizar la optimización #NRVO / #RVO y qué cosas podrían impedirla
- Finalmente, analizamos los costes de copia cuando tenemos que intercambiar los valores entre dos objetos preexistentes usando #std::swap y nuestra propia versión de #swap
- Entendiendo cómo debemos estructurar el código en #C++ para favorecer que las abstracciones no tengan coste
- Introduciendo la operación #move en C++ respecto a la copia. Esta operación tiene su base en el conocimiento de qué son #lvalues y #rvalues. 
- Rápida introducción a #lvalues y #rvalues y tarea pendiente para la próxima sesión