valores todas tipos retorno retornan que programacion las funciones funcion ejemplos ejemplo c++ visual-c++ gcc compiler-construction return

c++ - todas - valores de retorno en programacion



¿El compilador de c++ optimizará el valor de retorno no utilizado? (6)

Si tengo una función que devuelve un objeto, pero este valor de retorno nunca es utilizado por la persona que llama, ¿el compilador optimizará la copia? (Posiblemente una respuesta siempre / a veces / nunca).

Ejemplo elemental:

ReturnValue MyClass::FunctionThatAltersMembersAndNeverFails() { //Do stuff to members of MyClass that never fails return successfulResultObject; } void MyClass::DoWork() { // Do some stuff FunctionThatAltersMembersAndNeverFails(); // Do more stuff }

En este caso, ¿se ReturnValue objeto ReturnValue ? ¿Incluso se construye? (Sé que probablemente depende del compilador, pero reduzcamos esta discusión a las más populares y modernas).

EDITAR: Simplifiquemos esto un poco, ya que no parece haber consenso en el caso general. ¿Qué pasa si ReturnValue es un int, y devolvemos 0 en lugar de successfulResultObject ?


Dudo que la mayoría de los compiladores puedan hacer eso si estuvieran en diferentes objetos de compilación (es decir, diferentes archivos). Tal vez si ambos estuvieran en el mismo archivo, podrían.


El vinculador puede encargarse de este tipo de cosas, incluso si el llamador original y el llamado se encuentran en diferentes unidades de compilación.

Si tiene una buena razón para preocuparse por la carga de la CPU dedicada a una llamada a un método (la optimización prematura es la raíz de todo mal), puede considerar las muchas opciones de alineación disponibles para usted, incluida (¡jadeo!) Una macro.

¿REALMENTE necesita optimizar en este nivel?


Hay una buena posibilidad de que un optimizador de mirilla capte esto. Muchos (¿la mayoría?) Compiladores implementan uno, por lo que la respuesta probablemente sea "sí".

Como otros tienen notas, esta no es una pregunta trivial en el nivel de reescritura de AST.

Los optimizadores de mirilla funcionan en una representación del código a un nivel equivalente al lenguaje ensamblador (pero antes de la generación del código máquina real). Existe la posibilidad de notar la carga del valor de retorno en un registro seguido de una sobrescritura sin lectura intermedia, y simplemente eliminar la carga. Esto se hace caso por caso.


Lo más probable es que si el nivel de optimización hace que alineen el código. De lo contrario, tendrían que generar dos traducciones diferentes del mismo código para que funcione, lo que podría generar muchos problemas.


Si la clase ReturnValue tiene un constructor de copia no trivial, el compilador no debe eliminar la llamada al constructor de copia, sino el idioma invocado.

Si el constructor de copia está en línea, el compilador podría alinear la llamada, lo que a su vez podría causar la eliminación de gran parte de su código (también dependiendo de si FunctionThatAltersMembersAndNeverFails está en línea).


Si el valor de retorno es un int y devuelve 0 (como en la pregunta editada), puede optimizarse.

Tienes que mirar el ensamblaje subyacente. Si la función no está en línea, entonces el ensamblaje subyacente ejecutará un mov eax, 0 (o xor eax, eax) para establecer eax (que se usa generalmente para valores de retorno enteros) a 0. Si la función está en línea, esto seguramente optimizado de distancia.

Pero este senario no es demasiado útil si le preocupa lo que sucede cuando devuelve objetos de más de 32 bits. Tendrá que consultar las respuestas a la pregunta sin editar, que pintan una imagen bastante buena: si todo está alineado, la mayor parte se optimizará. Si no está en línea, entonces las funciones deben ser llamadas incluso si realmente no hacen nada, y eso incluye el constructor de un objeto (ya que el compilador no sabe si el constructor modificó las variables globales o hizo algo extraño) .