2012-04-06 22 views
13

En la mayoría de los casos, si quiero crear una característica opcional en C, simplemente crear dos funciones de la siguiente manera:¿Por qué GCC mantiene las funciones vacías?

#ifdef OPTIONAL_SOMETHING 
void do_something(int n, const char *s) 
{ 
    while (n--) { 
     printf("%s", s); 
    } 

    /* ...You might get the point, really do something... */ 
} 
#else 
void do_something(int n, const char *s) 
{ 
    /* Empty body */ 
} 
#endif 

Así que si no está definido el símbolo - cuando la función está desactivada - una función de vacío se compila en el ejecutable.

Profundizando en el listado de montaje, parece que GCC compila y pide las funciones vacías cuando las optimizaciones están desactivados. Si las optimizaciones están habilitadas, también con -O2 y -O3, compila solo el código de manejo de pila necesario, pero optimiza las instrucciones de la llamada. En general, mantiene la función.

Casi lo mismo aplica para los métodos no vacíos, pero no utilizados.

Simplemente debería descartar todo, pero no es así. ¿Por qué es el comportamiento predeterminado? Y solo por curiosidad: ¿cómo puedo eliminar esto?

+0

"Si las optimizaciones están habilitadas, también con -O2 y -O3 compila solo el código de manejo de pila necesario, pero optimiza las instrucciones de llamada". ¿Esto significa que todavía hay algunos gastos generales de esta manera? 'start_timer(); do_something(); stop_timer();' tarda más que 'start_timer(); stop_timer();'? –

Respuesta

24

Como la función tiene un enlace externo (no es static), el compilador no puede eliminarlo porque otro archivo de objetos podría hacer referencia a él. Si la función es static, se eliminará por completo.

+4

Eso aún deja la pregunta de por qué GCC no alinea el cuerpo de la función (es decir, omite la llamada) cuando se sabe que el cuerpo está vacío. – duskwuff

+1

@duskwuff: el compilador ha incluido funciones estáticas para que no pueda establecer puntos de interrupción en ellas, incluso cuando me gustaría. Sin embargo, podría depender de la versión de GCC o de la plataforma. De lo contrario, no sé; No he estado involucrado en el desarrollo de GCC y no estoy al tanto de las decisiones que se toman sobre tales asuntos. –

+1

Me pillaste la curiosidad así que lo intenté yo mismo: estoy en gcc 4.4.5 y con -O3 (solo) No veo que se llamen funciones vacías (ya sean estáticas o no). – timday

1

Si desea que el compilador finalmente alinee la función, debe decirle. Declare su función inline, esto permite que el compilador no emita la función si lo considera oportuno.

Ahora esto puede provocar un error de "símbolo indefinido" cuando compila con -O0 más o menos. Coloque una "instanciación" como

void do_something(int n, const char *s); 

en una sola unidad de compilación (archivo .c).

Cuestiones relacionadas