2010-01-25 15 views
5

¿Cómo se puede utilizar la optimización del valor de retorno ?
¿Hay algún caso en el que pueda confiar en un compilador moderno para usar la optimización, o siempre debo ir de forma segura y devolver un puntero de algún tipo/usar una referencia como parámetro?Confiando en la Optimización del Valor de Retorno

¿Existen casos conocidos en los que no se pueda realizar la optimización del valor de retorno ?, Me parece que la optimización del valor de retorno sería bastante fácil de realizar para un compilador.

+2

Tenga en cuenta que el compilador puede decidir _no_ hacer esto, cuando determina que el RVO no es realmente una optimización en el caso particular. Por lo tanto, no solo debe confiar en que el compilador lo haga cuando sea útil, sino que también debe confiar en que _no_ lo hará cuando sea inapropiado. – MSalters

+0

Para aclarar: un caso común en el que es inapropiado es cuando el tipo devuelto se puede pasar en un registro, p. una clase 'Radians'. La técnica de RVO usa el espacio asignado en la pila y, por lo tanto, tiene la sobrecarga de acceso a la memoria. – MSalters

+0

@MSalters Ok, es interesante saberlo. Básicamente, la optimización que me interesa es evitar, por ejemplo, un std :: vector <> para copiar. –

Respuesta

8

Siempre que las optimizaciones del compilador estén habilitadas (y en la mayoría de los compiladores, incluso cuando las optimizaciones sean deshabilitadas), se realizará el RVO. NRVO es ligeramente menos común, pero la mayoría de los compiladores también realizarán esta optimización, al menos cuando las optimizaciones están habilitadas.

Tienes razón, la optimización es bastante fácil de realizar para un compilador, por lo que los compiladores casi siempre lo hacen. Los únicos casos en los que "no se puede realizar" son aquellos en los que no se aplica la optimización: RVO solo se aplica cuando devuelve un temporal sin nombre. Si desea devolver una variable local con nombre, en su lugar se aplica NRVO, y si bien es un poco más complejo de implementar por un compilador, es factible y los compiladores modernos no tienen ningún problema.

+0

Especialmente, si tiene 2 variables con nombre y elige la que desea devolver en tiempo de ejecución, obviamente el compilador no puede realizar NRVO :) –

+0

Matthieu, supongo que lo mismo ocurre con dos salidas sin nombre. (es decir, "if (...) return A() else return B();" –

+0

@Viktor: No - eso es RVO, no ** N ** RVO. Solo se construirá uno de ellos. puede usar la misma memoria, que es la memoria reservada para el valor de retorno. Esa es la esencia de RVO: crear directamente el valor de retorno en la memoria reservada para él. – MSalters

2

para tener la mejor posibilidad de que se produzca, se puede devolver un objeto construido directamente en el estado de retorno [¿alguien puede recordar el nombre de este idioma - lo he olvidado]:

Foo f() { 
    .... 
    return Foo(...); 
} 

Pero como con todas las optimizaciones, el compilador siempre puede optar por no hacerlo. Y al final del día, si necesita devolver un valor, no hay alternativa a confiar en el compilador; los punteros y las referencias no lo cortarán.

Cuestiones relacionadas