So che la domanda riguarda GCC, ma ho pensato che potesse essere utile avere alcune informazioni su compilatori e altri compilatori.
L' noinline
attributo di funzione di GCC
è abbastanza popolare anche con altri compilatori. È supportato da almeno:
- Clang (verifica con
__has_attribute(noinline)
)
- Compilatore Intel C / C ++ (la loro documentazione è terribile, ma sono certo che funziona su 16.0+)
- Oracle Solaris Studio torna almeno a 12.2
- Compilatore ARM C / C ++ di nuovo almeno 4.1
- IBM XL C / C ++ indietro almeno alla 10.1
- TI 8.0+ (o 7.3+ con --gcc, che definirà
__TI_GNU_ATTRIBUTE_SUPPORT__
)
Inoltre, MSVC supporta
__declspec(noinline)
nuovamente Visual Studio 7.1. Probabilmente anche Intel lo supporta (cercano di essere compatibili con GCC e MSVC), ma non mi sono preoccupato di verificarlo. La sintassi è sostanzialmente la stessa:
__declspec(noinline)
static void foo(void) { }
IGP 10.2+ (e probabilmente precedente) supporta un noinline
pragma che si applica alla funzione successiva:
#pragma noinline
static void foo(void) { }
TI 6.0+ supporta un
FUNC_CANNOT_INLINE
pragma che (fastidiosamente) funziona diversamente in C e C ++. In C ++, è simile a IGP:
#pragma FUNC_CANNOT_INLINE;
static void foo(void) { }
In C, tuttavia, è richiesto il nome della funzione:
#pragma FUNC_CANNOT_INLINE(foo);
static void foo(void) { }
Cray 6.4+ (e possibilmente prima) adotta un approccio simile, richiedendo il nome della funzione:
#pragma _CRI inline_never foo
static void foo(void) { }
Oracle Developer Studio supporta anche un pragma che prende il nome della funzione, risalendo almeno a Forte Developer 6 , ma nota che deve venire dopo la dichiarazione, anche nelle versioni recenti:
static void foo(void);
#pragma no_inline(foo)
A seconda di quanto ti dedichi, potresti creare una macro che funzionerebbe ovunque, ma dovrai avere il nome della funzione e la dichiarazione come argomenti.
Se, OTOH, stai bene con qualcosa che funziona solo per la maggior parte delle persone, puoi cavartela con qualcosa che è un po 'più esteticamente piacevole e non richiede di ripeterti. Questo è l'approccio che ho adottato per Hedley , dove la versione attuale di
HEDLEY_NEVER_INLINE
è simile a:
#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 non vuoi usare Hedley (è un singolo dominio pubblico / intestazione CC0) puoi convertire la versione controllando le macro senza troppi sforzi, ma più di quanto io sia disposto a inserire ☺.