Sé que la pregunta es sobre GCC, pero pensé que podría ser útil tener información sobre compiladores y otros compiladores también.
El noinline
atributo de función de GCC también
es bastante popular entre otros compiladores. Es apoyado por al menos:
- Clang (consultar 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 ARM C / C ++ de nuevo al menos a 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, MSVC admite
__declspec(noinline)
volver a Visual Studio 7.1. Intel probablemente también lo admite (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) admite un noinline
pragma que se aplica a la siguiente función:
#pragma noinline
static void foo(void) { }
TI 6.0+ admite un
FUNC_CANNOT_INLINE
pragma que (molestamente) funciona de manera diferente en C y C ++. En C ++, es similar a los 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) adopta 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, volviendo 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 lo dedicado que 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 las personas, puedes salirte con la tuya con algo que es un poco más estéticamente agradable y que no requiere repetirse. Ese es el enfoque que he tomado para Hedley , donde la versión actual de
HEDLEY_NEVER_INLINE se
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)
# define HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
#else
# define HEDLEY_NEVER_INLINE HEDLEY_INLINE
#endif
Si no desea utilizar Hedley (es un solo dominio público / encabezado CC0), puede convertir la versión que comprueba las macros sin demasiado esfuerzo, pero más de lo que estoy dispuesto a poner ☺.