Au lieu de répondre "qu'est-ce que ça fait ?", je réponds "comment faire pour que ça fasse ce que je veux ?". Il y a 5 types d'inlining, tous disponibles dans GNU C89, C99 standard, et C++. MSVC a un peu de d'entre eux (notez que je n'ai pas testé le code MSVC)
toujours en ligne, sauf si l'adresse est prise
Ajouter __attribute__((always_inline))
à toute déclaration, puis utilisez l'un des cas ci-dessous pour gérer la possibilité que son adresse soit prise.
Vous ne devriez probablement jamais l'utiliser, sauf si vous avez besoin de sa sémantique (par exemple pour affecter l'assemblage d'une certaine manière, ou pour utiliser alloca
). Le compilateur sait généralement mieux que vous si cela en vaut la peine.
MSVC a __forceinline
qui semble être le même, mais apparemment, il refuse de s'aligner dans un certain nombre de circonstances courantes (par exemple, lorsque l'optimisation est désactivée) alors que d'autres compilateurs s'en sortent très bien.
inline et émettre un symbole faible (comme en C++, c'est-à-dire "faites que ça marche")
__attribute__((weak))
void foo(void);
inline void foo(void) { ... }
Notez que cela laisse un tas de copies du même code, et le linker en choisit une arbitrairement.
MSVC ne semble pas avoir d'équivalent exact en mode C, bien qu'il y ait un certain nombre de choses similaires. __declspec(selectany)
semble ne parler que des données, et ne s'applique donc peut-être pas aux fonctions ? Il existe également un support de linker pour alias faibles mais est-ce que ça marche ici ?
en ligne, mais n'émettent jamais de symbole (laissant des références externes)
__attribute__((gnu_inline))
extern inline void foo(void) { ... }
MSVC's __declspec(dllimport)
combiné à une définition réelle (par ailleurs inhabituelle), est censé faire cela.
émettre toujours (pour un TU, pour résoudre ce qui précède)
La version hinted émet un symbole faible en C++, mais un symbole fort dans l'un ou l'autre dialecte du C :
void foo(void);
inline void foo(void) { ... }
Ou vous pouvez le faire sans l'indice, qui émet un symbole fort dans les deux langues :
void foo(void) { ... }
En général, vous savez quel est le langage de votre UT lorsque vous fournissez les définitions, et vous n'avez probablement pas besoin de beaucoup d'inlining.
MSVC's __declspec(dllexport)
est censé le faire.
en ligne et émettent dans chaque TU
static inline void foo(void) { ... }
Pour tous ces éléments, sauf le static
un, vous pouvez ajouter un void foo(void)
déclaration ci-dessus. Cela permet de respecter la "meilleure pratique" consistant à écrire des en-têtes propres, alors #include
dans un fichier séparé avec les définitions en ligne. Ensuite, si vous utilisez des inlines de style C, #define
une macro différente dans une TU dédiée pour fournir les définitions hors ligne.
N'oubliez pas extern "C"
si l'en-tête peut être utilisé à la fois en C et en C++ !
Il y a aussi quelques éléments connexes :
jamais en ligne
Ajouter __attribute__((noinline))
à toute déclaration de la fonction.
MSVC a __declspec(noinline)
mais il est documenté pour ne fonctionner que pour les fonctions membres. Cependant, j'ai vu la mention d'"attributs de sécurité" qui pourraient empêcher l'inlining ?
obliger les autres fonctions à être intégrées dans celle-ci si possible.
Ajouter __attribute__((flatten))
à toute déclaration de la fonction.
Notez que noinline
est plus puissant que cela, tout comme les fonctions dont la définition n'est pas connue au moment de la compilation.
MSVC ne semble pas avoir d'équivalent. J'ai vu une seule mention de [[msvc::forceinline_calls]]
(appliqué à une déclaration ou un bloc), mais il n'est pas récursif.