Pregunta

Me gustaría asegurarme de que mis rutinas están aprovechando (N)RVO siempre que sea posible.Otro que analizar a través de la resultante de desmontaje, ¿hay algo que puedo hacer o comprobar para ver si la rutina está compilado con (N)RVO?En este momento estoy más interesado en MSVC y GCC.

¿Fue útil?

Solución

No, realmente no.

Sin embargo, usted puede seguir las directrices a la hora de escribir el código.


Sin Nombre Valor De Retorno De La Optimización De La

Esto es bastante activa cada vez que regreso de un temporal, incluso en modo de Depuración.

return MyObject(....);

Nombre Valor De Retorno De La Optimización De La

Esto es bastante activa cada vez que la función siempre devuelve el mismo objeto temporal:

MyObject func() {
  MyObject result;
  if (...) { return result; }

  result.push(0);
  return result;
}

Usted puede mezclar esos, sino que se convierte en casi imposible para el compilador para aplicar RVO en este caso:

MyObject func() {
  MyObject result;
  if (...) { return MyObject(...); }

  return result;
}

Aquí, es probable que uno de regreso se beneficiarán de RVO y el otro no.Y apostaría a que en el primer ser optimizado porque se estaría atascado si usted forma especulativa crear result en el retorno de la ranura y de repente necesita tomar el if la rama.Tenga en cuenta que sólo el reordenamiento de las declaraciones sólo el trabajo:

MyObject func() {
  if (...) { return MyObject(...); }

  MyObject result;

  return result;
}

Así que la regla de oro para NRVO es que no debe haber return instrucción entre la declaración de result y el return result; declaración que volver otra cosa que result sí.


Si usted sigue este, apilar las probabilidades en su favor.Y entonces es sólo una cuestión de revisión de código.

Y también hacer que su código sea más fácil de leer debido a que usted no declarar las variables antes de saber que usted realmente necesita!

Otros consejos

Puede agregar métodos de depuración al destructor:

struct A
{
   ~A() { cout << "destructor called"; }
};

A foo()
{
   A a;
   return a;
}

Si se llama al destructor, probablemente RVO no se aplicó.

Formas posibles que puedo pensar son:

  1. implementando un mecanismo de conteo de referencia dentro de su clase que realiza un seguimiento de la cantidad de instancias creadas a través de la clase, algo casi como lo hace un shared_ptr, de esta manera puede detectar copias adicionales de su clase que se está creando y eliminar siLa opción de copia no está sucediendo.

  2. Puede simplemente poner las huellas de depuración en la copia constructor y destructor para su clase, si no está sucediendo copia la elision, vería un montón de sucesivos trazos de depuración de copias y destructores.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top