inline
indique au compilateur d' essayer d' incorporer le contenu de la fonction dans le code appelant au lieu d'exécuter un appel réel.
Pour les petites fonctions appelées fréquemment qui peuvent faire une grande différence de performances.
Cependant, ce n'est qu'un "indice", et le compilateur peut l'ignorer, et la plupart des compilateurs essaieront de "insérer" même lorsque le mot-clé n'est pas utilisé, dans le cadre des optimisations, lorsque c'est possible.
par exemple:
static int Inc(int i) {return i+1};
.... // some code
int i;
.... // some more code
for (i=0; i<999999; i = Inc(i)) {/*do something here*/};
Cette boucle serrée effectuera un appel de fonction à chaque itération, et le contenu de la fonction est en fait nettement inférieur au code que le compilateur doit mettre pour effectuer l'appel. inline
demandera essentiellement au compilateur de convertir le code ci-dessus en un équivalent de:
int i;
....
for (i=0; i<999999; i = i+1) { /* do something here */};
Sauter l'appel et le retour de la fonction réelle
Évidemment, c'est un exemple pour montrer le point, pas un vrai morceau de code.
static
fait référence à la portée. En C, cela signifie que la fonction / variable ne peut être utilisée que dans la même unité de traduction.
static
fait référence à la portée. En C, cela signifie que la fonction / variable ne peut être utilisée que dans la même unité de traduction.static
(avec ou sansinline
) peut être parfaitement bien dans l'en-tête, ne voyez aucune raison pourquoi pas. Les modèles sont pour C ++, cette question concerne C.inline
est un bon style, imoinline
ne pas donner des instructions au compilateur de faire toute tentative de inline. Il permet simplement au programmeur d'inclure le corps de la fonction dans plusieurs unités de traduction sans violation de l'ODR. Un effet secondaire de ceci est que cela permet au compilateur, quand il mettrait en ligne la fonction, de le faire.Par défaut, une définition en ligne n'est valide que dans l'unité de traduction actuelle.
Si la classe de stockage est
extern
, l'identificateur a une liaison externe et la définition en ligne fournit également la définition externe.Si la classe de stockage est
static
, l'identifiant a une liaison interne et la définition en ligne est invisible dans les autres unités de traduction.Si la classe de stockage n'est pas spécifiée, la définition en ligne n'est visible que dans l'unité de traduction actuelle, mais l'identifiant a toujours un lien externe et une définition externe doit être fournie dans une unité de traduction différente. Le compilateur est libre d'utiliser la définition en ligne ou externe si la fonction est appelée dans l'unité de traduction actuelle.
Comme le compilateur est libre d'insérer (et non en ligne) toute fonction dont la définition est visible dans l'unité de traduction actuelle (et, grâce aux optimisations de temps de liaison, même dans différentes unités de traduction, bien que le standard C ne prenne pas vraiment en compte that), dans la plupart des cas, il n'y a aucune différence entre les définitions de fonction
static
etstatic inline
.Le
inline
spécificateur (comme laregister
classe de stockage) n'est qu'un indice du compilateur, et le compilateur est libre de l'ignorer complètement. Les compilateurs non optimisés conformes aux normes n'ont qu'à honorer leurs effets secondaires, et les compilateurs d'optimisation feront ces optimisations avec ou sans conseils explicites.inline
etregister
ne sont pas inutiles, cependant, car ils demandent au compilateur de lancer des erreurs lorsque le programmeur écrit du code qui rendrait les optimisations impossibles: uneinline
définition externe ne peut pas référencer des identifiants avec un lien interne (car ils ne seraient pas disponibles dans une unité de traduction différente) ou définissez des variables locales modifiables avec une durée de stockage statique (car elles ne partageraient pas l'état entre les unités de traduction), et vous ne pouvez pas prendre d'adresses deregister
variables qualifiées.Personnellement, j'utilise également la convention pour marquer
static
les définitions de fonctions dans les en-têtesinline
, car la principale raison pour laquelle les définitions de fonctions sont placées dans les fichiers d'en-tête est de les rendre inlinables.En général, je n'utilise que des définitions de
static inline
fonction et d'static const
objet en plus desextern
déclarations dans les en-têtes.Je n'ai jamais écrit de
inline
fonction avec une classe de stockage différente destatic
.la source
inline
comme si elle s'appliquait réellement à l'inlining est trompeuse et sans doute incorrecte. Aucun compilateur moderne ne l'utilise comme un indice pour l'inline ou l'exige afin d'activer l'inlining d'une fonction.static
etstatic inline
. Les deux rendent la définition invisible aux autres unités de traduction. Alors, quelle serait une raison raisonnable d'écrire à lastatic inline
placestatic
?D'après mon expérience avec GCC, je le sais
static
etstatic inline
diffère en quelque sorte de la manière dont le compilateur émet des avertissements sur les fonctions inutilisées. Plus précisément, lorsque vous déclarez unestatic
fonction et qu'elle n'est pas utilisée dans l'unité de traduction actuelle, le compilateur produit un avertissement concernant une fonction inutilisée, mais vous pouvez empêcher cet avertissement en le changeant enstatic inline
.Ainsi, j'ai tendance à penser que cela
static
devrait être utilisé dans les unités de traduction et bénéficier d'un compilateur de vérification supplémentaire pour trouver les fonctions inutilisées. Etstatic inline
devrait être utilisé dans les fichiers d'en-tête pour fournir des fonctions qui peuvent être intégrées (en raison de l'absence de lien externe) sans émettre d'avertissements.Malheureusement, je ne trouve aucune preuve de cette logique. Même à partir de la documentation de GCC, je n'ai pas pu conclure que cela
inline
inhibe les avertissements de fonction inutilisés. J'apprécierais si quelqu'un partageait des liens vers une description de cela.la source
warning: unused function 'function' [clang-diagnostic-unused-function]
pour unestatic inline
fonction lors de la construction avecclang-tidy
(v8.0.1), qui est utilisée dans une autre unité de traduction. Mais certainement, c'est l'une des meilleures explications et raison de combinerstatic
&inline
!En C,
static
signifie que la fonction ou la variable que vous définissez ne peut être utilisée que dans ce fichier (c'est-à-dire l'unité de compilation)Alors,
static inline
signifie la fonction en ligne qui ne peut être utilisée que dans ce fichier.ÉDITER:
L'unité de compilation doit être l' unité de traduction
la source
the compile unit
c'est quelque chose que j'ai écrit par erreur, il n'y a rien de tel, la terminologie réelle esttranslation unit
Une différence qui n'est pas au niveau du langage mais au niveau de l'implémentation populaire: certaines versions de gcc supprimeront les
static inline
fonctions non référencées de la sortie par défaut, mais conserveront lesstatic
fonctions simples même si elles ne sont pas référencées. Je ne sais pas à quelles versions cela s'applique, mais d'un point de vue pratique, cela signifie qu'il peut être judicieux de toujours utiliserinline
pour lesstatic
fonctions dans les en-têtes.la source
inline
dans la définition? Voulez-vous également ne pas l'utiliser pour lesextern
fonctions?attribute((used))
et son utilisation pour permettre à asm de référencer desstatic
fonctions et des données autrement non référencées .