sirve que para make hacer entre diferencia con compilar como c gcc inline

c - que - makefile linux



¿Cómo puedo decirle a gcc que no ponga en línea una función? (8)

Desea el atributo noinline específico de gcc .

Este atributo de función evita que se considere una función para alinear. Si la función no tiene efectos secundarios, existen optimizaciones distintas de la línea interna que hacen que las llamadas a funciones se optimicen, aunque la llamada a la función es en vivo. Para evitar que esas llamadas se optimicen, coloque asm ("");

Úselo así:

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

Digamos que tengo esta pequeña función en un archivo fuente

static void foo() {}

y construyo una versión optimizada de mi binario, pero no quiero que esta función esté en línea (para fines de optimización). ¿Existe una macro que pueda agregar en un código fuente para evitar la creación de líneas?


En caso de que obtenga un error de __attribute__((noinline)) para __attribute__((noinline)) , puede simplemente intentar:

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


GCC tiene un interruptor llamado

-fno-inline-small-functions

Así que úsalo cuando evoques gcc. Pero el efecto secundario es que todas las otras funciones pequeñas tampoco están en línea.


Sé que la pregunta es sobre GCC, pero pensé que podría ser útil tener también información sobre compiladores y otros compiladores.

El atributo de función noinline de GCC es bastante popular también con otros compiladores. Es apoyado por al menos:

  • Clang (verificar con __has_attribute(noinline) )
  • Compilador Intel C / C ++ (su documentación es terrible, pero estoy seguro de que funciona en 16.0+)
  • Oracle Solaris Studio vuelve al menos a 12.2
  • Compilador de ARM C / C ++ de nuevo a al menos 4.1
  • IBM XL C / C ++ vuelve al menos a 10.1
  • TI 8.0+ (o 7.3+ con --gcc, que definirá __TI_GNU_ATTRIBUTE_SUPPORT__ )

Además, __declspec(noinline) admite __declspec(noinline) vuelta a Visual Studio 7.1. Intel probablemente también lo respalde (intentan ser compatibles tanto con GCC como con MSVC), pero no me he molestado en verificarlo. La sintaxis es básicamente la misma:

__declspec(noinline) static void foo(void) { }

PGI 10.2+ (y probablemente más antiguo) es compatible con un pragma noinfinito que se aplica a la siguiente función:

#pragma noinline static void foo(void) { }

TI 6.0+ admite un pragma FUNC_CANNOT_INLINE que (molestamente) funciona de manera diferente en C y C ++. En C ++, es similar a las IGP:

#pragma FUNC_CANNOT_INLINE; static void foo(void) { }

En C, sin embargo, se requiere el nombre de la función:

#pragma FUNC_CANNOT_INLINE(foo); static void foo(void) { }

Cray 6.4+ (y posiblemente antes) toma un enfoque similar, que requiere el nombre de la función:

#pragma _CRI inline_never foo static void foo(void) { }

Oracle Developer Studio también admite un pragma que toma el nombre de la función, que se remonta al menos a Forte Developer 6 , pero tenga en cuenta que debe venir después de la declaración, incluso en versiones recientes:

static void foo(void); #pragma no_inline(foo)

Dependiendo de cuán dedicado esté, podría crear una macro que funcionaría en todas partes, pero necesitaría tener el nombre de la función y la declaración como argumentos.

Si, OTOH, estás de acuerdo con algo que simplemente funciona para la mayoría de la gente, puedes salirte con la tuya con algo que es un poco más estético y no es necesario que te repitas. Ese es el enfoque que he tomado para Hedley , donde la versión actual de HEDLEY_NEVER_INLINE ve así:

#if / HEDLEY_GNUC_HAS_ATTRIBUTE(noinline,4,0,0) || / HEDLEY_INTEL_VERSION_CHECK(16,0,0) || / HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || / HEDLEY_ARM_VERSION_CHECK(4,1,0) || / HEDLEY_IBM_VERSION_CHECK(10,1,0) || / HEDLEY_TI_VERSION_CHECK(8,0,0) || / (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) # define HEDLEY_NEVER_INLINE __attribute__((__noinline__)) #elif HEDLEY_MSVC_VERSION_CHECK(13,10,0) # define HEDLEY_NEVER_INLINE __declspec(noinline) #elif HEDLEY_PGI_VERSION_CHECK(10,2,0) # define HEDLEY_NEVER_INLINE _Pragma("noinline") #elif HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus) # define HEDLEY_NO_RETURN _Pragma("FUNC_CANNOT_INLINE;") #else # define HEDLEY_NEVER_INLINE HEDLEY_INLINE #endif

Si no quiere usar Hedley (es un solo dominio público / encabezado CC0) puede convertir las macros de comprobación de versión sin demasiado esfuerzo, pero más de lo que estoy dispuesto a poner ☺.


Una forma portátil de hacerlo es llamar a la función a través de un puntero:

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

Aunque esto produce diferentes instrucciones para ramificar, que puede no ser tu objetivo. Lo cual trae a colación un buen punto: ¿cuál es tu objetivo aquí?


Use el noinline noinline :

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

Probablemente debería usarlo tanto cuando declara la función para uso externo como cuando escribe la función.


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. __attribute__((noinline)) la __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.


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

Esto es lo que funcionó para mí.