Eu sei que a pergunta é sobre o GCC, mas achei que poderia ser útil ter algumas informações sobre outros compiladores.
O noinline
atributo de função do GCC também
é bastante popular com outros compiladores. É suportado por pelo menos:
- Clang (verifique com
__has_attribute(noinline)
)
- Compilador Intel C / C ++ (a documentação deles é terrível, mas tenho certeza de que funciona no 16.0+)
- Oracle Solaris Studio volta a pelo menos 12.2
- Compilador ARM C / C ++ de volta a pelo menos 4.1
- IBM XL C / C ++ de volta a pelo menos 10.1
- TI 8.0+ (ou 7.3+ com --gcc, que definirá
__TI_GNU_ATTRIBUTE_SUPPORT__
)
Além disso, o MSVC oferece suporte
__declspec(noinline)
ao Visual Studio 7.1. A Intel provavelmente também suporta (eles tentam ser compatíveis com o GCC e o MSVC), mas não me preocupei em verificar isso. A sintaxe é basicamente a mesma:
__declspec(noinline)
static void foo(void) { }
A PGI 10.2+ (e provavelmente mais antiga) suporta um noinline
pragma que se aplica à próxima função:
#pragma noinline
static void foo(void) { }
A TI 6.0+ suporta um
FUNC_CANNOT_INLINE
pragma que (irritantemente) funciona de maneira diferente em C e C ++. No C ++, é semelhante ao IGP:
#pragma FUNC_CANNOT_INLINE;
static void foo(void) { }
Em C, no entanto, o nome da função é necessário:
#pragma FUNC_CANNOT_INLINE(foo);
static void foo(void) { }
O Cray 6.4+ (e possivelmente anterior) adota uma abordagem semelhante, exigindo o nome da função:
#pragma _CRI inline_never foo
static void foo(void) { }
O Oracle Developer Studio também suporta um pragma que leva o nome da função, que remonta a pelo menos o Forte Developer 6 , mas observe que ele precisa vir após a declaração, mesmo nas versões recentes:
static void foo(void);
#pragma no_inline(foo)
Dependendo de como você é dedicado, é possível criar uma macro que funcione em qualquer lugar, mas é necessário ter o nome da função e a declaração como argumentos.
Se, OTOH, você concorda com algo que simplesmente funciona para a maioria das pessoas, você pode se safar de algo que é um pouco mais esteticamente agradável e não exige repetição. Essa é a abordagem que adotei para Hedley , onde a versão atual do
HEDLEY_NEVER_INLINE se
parece:
#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
Se você não quiser usar o Hedley (é um único cabeçalho de domínio público / CC0), poderá converter as macros de verificação de versão sem muito esforço, mas mais do que estou disposto a colocar ☺.