Je sais que la question concerne GCC, mais j'ai pensé qu'il pourrait être utile d'avoir des informations sur les compilateurs d'autres compilateurs également.
L' noinline
attribut function de GCC
est également très populaire auprès d'autres compilateurs. Il est soutenu par au moins:
- Clang (vérifier avec
__has_attribute(noinline)
)
- Compilateur Intel C / C ++ (leur documentation est terrible, mais je suis certain que cela fonctionne sur 16.0+)
- Oracle Solaris Studio de retour à au moins 12.2
- Compilateur ARM C / C ++ de retour à au moins 4.1
- IBM XL C / C ++ de retour à au moins 10.1
- TI 8.0+ (ou 7.3+ avec --gcc, qui définira
__TI_GNU_ATTRIBUTE_SUPPORT__
)
En outre, MSVC prend __declspec(noinline)
en charge le
retour à Visual Studio 7.1. Intel le supporte probablement aussi (ils essaient d'être compatibles avec GCC et MSVC), mais je n'ai pas pris la peine de le vérifier. La syntaxe est fondamentalement la même:
__declspec(noinline)
static void foo(void) { }
PGI 10.2+ (et probablement plus ancien) prend en charge un noinline
pragma qui s'applique à la fonction suivante:
#pragma noinline
static void foo(void) { }
TI 6.0+ prend en charge un
FUNC_CANNOT_INLINE
pragma qui (ennuyeusement) fonctionne différemment en C et C ++. En C ++, c'est similaire à PGI:
#pragma FUNC_CANNOT_INLINE;
static void foo(void) { }
En C, cependant, le nom de la fonction est obligatoire:
#pragma FUNC_CANNOT_INLINE(foo);
static void foo(void) { }
Cray 6.4+ (et peut-être plus tôt) adopte une approche similaire, nécessitant le nom de la fonction:
#pragma _CRI inline_never foo
static void foo(void) { }
Oracle Developer Studio prend également en charge un pragma qui prend le nom de la fonction, remontant au moins à Forte Developer 6 , mais notez qu'il doit venir après la déclaration, même dans les versions récentes:
static void foo(void);
#pragma no_inline(foo)
En fonction de votre dévouement, vous pouvez créer une macro qui fonctionnerait partout, mais vous auriez besoin d'avoir le nom de la fonction ainsi que la déclaration comme arguments.
Si, OTOH, vous êtes d'accord avec quelque chose qui fonctionne juste pour la plupart des gens, vous pouvez vous en tirer avec quelque chose qui est un peu plus esthétique et ne nécessite pas de vous répéter. C'est l'approche que j'ai adoptée pour Hedley , où la version actuelle de
HEDLEY_NEVER_INLINE
ressemble à:
#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 vous ne voulez pas utiliser Hedley (c'est un seul en-tête de domaine public / CC0), vous pouvez convertir les macros de vérification de version sans trop d'effort, mais plus que je ne suis prêt à en mettre ☺.