2011-08-30 13 views
6

GCC enuncia una afirmación, sin importar cuánto trate de evitarla. ProbéCómo evitar que GCC se alinee

  • -fno-inline
  • -O0
  • __attribute__ ((noinline))
  • dummy asm("")

Sin éxito! Aquí el código:

#include<iostream> 

using namespace std; 

struct A { 
    A() {cout << "A::A()" <<endl; } 
    A(const A& a) {cout << "A::A(copy)" <<endl; } 
    A& operator=(const A& a) {cout << "A::=()" <<endl; return *this;} 
}; 

A __attribute__ ((noinline)) func() 
{ 
    cout << "func()" << endl; 
    A loc; 
    asm(""); 
    return loc; 
} 

int main() { 
    A a = func(); 
} 

La desafortunada salida de este (g ++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2) es

func() 
A::A() 

¿Qué pasó con la declaración a = func(); ??

La razón de este experimento es que me gustaría saber lo que sucede cuando la ejecución llega a esta declaración (porque necesito controlar cómo se hace esto):

A a = func(); 

leí que el constructor de copia se llama cuando uno hace

A a = b; 

(en este caso, el constructor de copia se llama, pero no en el caso a a = func();). la función se colocarán en línea en su lugar. I NECESIDAD control sobre esta declaración ya que mi "estructura A" en la vida real contiene datos dinámicamente asignados que deben ser atendidos.

¿Me falta algo obvio aquí?

+2

Prueba '-fno-elide-constructors'. (Y tenga en cuenta que usted declaró sus constructores en línea en virtud de definirlos dentro de la definición de la clase.) –

+1

¿Realmente está en línea? Se parece a RVO para mí. –

+0

¡Gracias por la respuesta! De hecho, no está en línea. Es optimización Con esto veré si mi estructura de vida real funciona. (Por el momento no). Una pregunta: ¿Puede desactivar esta posibilidad de optimización (-fno-elide-constructors) cambiar el comportamiento del programa (digamos si el constructor de copia contiene código vital) excepto la velocidad? – ritter

Respuesta

15

No, esto no tiene nada que ver con la función que está en línea. Alinear la función no cambiaría el comportamiento observable.

Esta es una optimización llamada elisión de copia que permite al compilador evitar una copia construyendo el valor de retorno directamente en el destino. Puede deshabilitarlo con la bandera g ++ -fno-elide-constructors.

En cualquier caso, los datos dinámicamente asignados no deberían ser un problema. Asumiendo un constructor de copia cuerdo, la única diferencia que verá será posiblemente un mejor rendimiento.

5

Si struct A contiene datos asignados dinámicamente, entonces es su responsabilidad administrar esa memoria en el destructor/constructor apropiado. Muchas clases administran datos dinámicamente asignados y funcionan perfectamente con copias elípticas. RVO y NRVO son optimizaciones importantes.

Cuestiones relacionadas