2012-04-06 9 views
10

En una entrevista de programación que tuve ayer, uno de los programas que tenía que escribir llegó a tener algo como esto:RVO para los tipos definidos por el usuario complejas en C++

struct Blob 
{ 
    // basic field containing image blob statistics. 
}; 

std::vector<Blob> find_blobs (const Image& ...) 
{ 
    std::vector<Blob> blobs; 
    // ... 
    return blobs; 
} 

Estoy familiarizado con return value optimization (RVO), así que acabo de mencionar que devolver el vector no causaría una copia en los compiladores populares (hay una declaración de devolución única como la última línea, y ninguna ruta de control puede devolver otro objeto en el código que escribí).

Sin embargo, el entrevistador me dijo que dado que Blob puede ser un tipo complejo definido por el usuario (UDT), el compilador puede no ser capaz de realizar RVO. Añadió que devolver un std::vector<Blob*> aumentaría las posibilidades de que el compilador realice la elisión de copia.

Según mi entender, la capacidad del compilador para realizar RVO es completamente irrelevante para el tipo de objeto que se devuelve, salvo para objetos no copiables, para los cuales el compilador (¿debería?) Rechazar el código incluso si el código resultante podría compilar sin invocar el constructor de copia.

Entonces, ¿fue el entrevistador cierto? ¿Puede un tipo de devolución compleja evitar que el compilador aplique RVO?

+4

Quien sea que te estaba entrevistando, yo no contrataría. :) –

+0

@ Robᵩ: No estoy diciendo quién era o para quién trabajan (o la pregunta real de la entrevista) :-) –

Respuesta

7

No, los tipos utilizados no deberían afectar la optimización.

La única razón por la que veo utilizar punteros sería que son más baratos para copiar si el compilador falla el RVO. No es probable con los compiladores más populares.

+0

De hecho, si el compilador realizara una copia, copiaría un vector de punteros sería más barato (aunque en este caso, 'BLOB' era un POD con 2-3 campos de tipos primitivos que daban como resultado un' memcpy() 'ligeramente mayor). Sin embargo, eso requeriría una gestión de memoria explícita por parte de la persona que llama y trato de evitar eso tanto como sea posible. –

+0

Sí, no se recomienda el uso del puntero a menos que se lo fuerce. Los compiladores como g ++ realizan esta optimización incluso en el nivel de optimización más bajo, '-O0'. Pero no sé qué está usando su posible empleador (?). ;-) –

+0

Sí, creo que g ++ siempre aplica RVO a menos que lo desactives explícitamente usando '-fno-elide-constructors'. MSVC 2008 lo realiza incluso en modo de depuración (acabo de verificarlo con un ejemplo). AFAIK, este potencial empleador usa todos los compiladores populares (bueno, al menos g ++ y MSVC). –

Cuestiones relacionadas