Réponses:
inlineindique 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. inlinedemandera 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.
staticfait 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 sans inline) 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.
inlineest un bon style, imo
inlinene 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 staticet static inline.
Le inlinespécificateur (comme la registerclasse 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.
inlineet registerne sont pas inutiles, cependant, car ils demandent au compilateur de lancer des erreurs lorsque le programmeur écrit du code qui rendrait les optimisations impossibles: une inlinedé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 de registervariables qualifiées.
Personnellement, j'utilise également la convention pour marquer staticles définitions de fonctions dans les en-têtes inline, 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 inlinefonction et d' static constobjet en plus des externdéclarations dans les en-têtes.
Je n'ai jamais écrit de inlinefonction avec une classe de stockage différente de static.
inlinecomme 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.
staticet static inline. Les deux rendent la définition invisible aux autres unités de traduction. Alors, quelle serait une raison raisonnable d'écrire à la static inlineplace static?
D'après mon expérience avec GCC, je le sais staticet static inlinediffè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 une staticfonction 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 en static inline.
Ainsi, j'ai tendance à penser que cela staticdevrait ê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. Et static inlinedevrait ê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 inlineinhibe les avertissements de fonction inutilisés. J'apprécierais si quelqu'un partageait des liens vers une description de cela.
warning: unused function 'function' [clang-diagnostic-unused-function]pour une static inlinefonction lors de la construction avec clang-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 combiner static& 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
the compile unitc'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 inlinefonctions non référencées de la sortie par défaut, mais conserveront les staticfonctions 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 utiliser inlinepour les staticfonctions dans les en-têtes.
inlinedans la définition? Voulez-vous également ne pas l'utiliser pour les externfonctions?
attribute((used))et son utilisation pour permettre à asm de référencer des staticfonctions et des données autrement non référencées .
staticfait 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.