2009-09-24 10 views
90

Decir que tengo esta pequeña función en un archivo de origen¿Cómo puedo decirle a gcc que no ponga en línea una función?

static void foo() {} 

y construyo una versión optimizada de mi binaria sin embargo, yo no quiero esta función inline (con fines de optimización). ¿Existe una macro que pueda agregar en un código fuente para evitar la creación de líneas?

+0

Gracias por esta pregunta! Estaba perfilando con oprofile cuando una función no apareció, las respuestas aquí arreglaron esto. –

Respuesta

108

Desea el atributo gcc -específico noinline.

This function attribute prevents a function from being considered for inlining. If the function does not have side-effects, there are optimizations other than inlining that causes function calls to be optimized away, although the function call is live. To keep such calls from being optimized away, put asm ("");

utilizar de esta manera:

void __attribute__ ((noinline)) foo() 
{ 
    ... 
} 
+29

Usando gcc 4.4.3 en Arch Linux, obtengo un error de sintaxis con el atributo colocado como se indicó anteriormente. Funciona correctamente cuando precede a la función (por ejemplo, __attribute__ ((noinline)) void foo() {}) – mrkj

+2

Arduino también lo quería colocar antes de la función. –

+2

Editado para corregir la sintaxis del atributo. – Quuxplusone

7

Uso del noinlineattribute:

int func(int arg) __attribute__((noinline)) 
{ 
} 

Probablemente debería utilizar tanto cuando se declara la función de uso externo y cuando se escribe la función.

21

una manera portátil para hacer esto es llamar a la función a través de un puntero:

void (*foo_ptr)() = foo; 
foo_ptr(); 

Aunque esto produce diferentes instrucciones en rama, la cual puede no ser tu objetivo. Lo que trae a colación un buen punto: ¿qué es su objetivo aquí?

+12

No siempre funcionará. Algunos compiladores aún pueden optimizar eso ... –

+0

Si el puntero se define en el alcance del archivo, y no es estático, debería funcionar, ya que el compilador no puede asumir que tiene su valor inicial en el momento del uso. Si es un local (como se muestra), es casi seguro que se trata lo mismo que foo(). ("En esta década", agregó, mirando las fechas) – greggo

13

En caso de que un error de compilador para __attribute__((noinline)), sólo puede intentar:

noinline int func(int arg) 
{ 
    .... 
} 
+1

+1 Funcionó para mí cuando ninguna de las otras lo hizo – Andres

+2

Me aparece un error: noinline no nombra un tipo. – AlwaysLearning

9
static __attribute__ ((noinline)) void foo() 
{ 

} 

Esto es lo que funcionó para mí.

25

GCC tiene una opción denominada

-fno-inline-small-functions

Así que utilizar al evocar gcc. Pero el efecto secundario es que todas las otras funciones pequeñas tampoco están en línea.

+0

No funcionó al nivel de compilador. Estaba usando gcc 5.2.1 20150902 (Red Hat 5.2.1-2) –

0

Yo trabajo con gcc 7.2. Específicamente necesitaba que una función no estuviera en línea, porque tenía que crearse una instancia en una biblioteca. Probé la respuesta __attribute__((noinline)), así como la respuesta asm(""). Ninguno de los dos resolvió el problema.

Finalmente, calculé que la definición de una variable estática dentro de la función forzará al compilador a asignarle espacio en el bloque de variable estática y emitirá una inicialización cuando se llame por primera vez a la función.

Esto es una especie de truco sucio, pero funciona.

+0

Puede definir su función 'inline void foo (void) {...}' en un encabezado y declararlo 'extern inline void foo (void) ; 'en un archivo fuente de la biblioteca. Siguiendo la semántica C99, el compilador podría alinear la función cuando le plazca Y emitir código objeto en su biblioteca. Ver [¿Está "en línea" sin "estático" o "externo" alguna vez útil en C99?] (Https://stackoverflow.com/questions/6312597/is-inline-without-static-or-extern-ever-useful-in -c99). – diapir

Cuestiones relacionadas