Quelle est la différence entre la fonction «statique» et la fonction «statique en ligne»?

IMO permet à la fonction d’avoir une scope de l’unité de traduction uniquement.

Quelle est la différence entre la fonction “statique” et la fonction “statique en ligne“?

Pourquoi devrait-on placer en inline dans un fichier d’en-tête, pas dans le fichier .c ?

inline demande au compilateur d’ essayer d’ intégrer le contenu de la fonction dans le code d’appel au lieu d’exécuter un appel réel.

Pour les petites fonctions appelées fréquemment, cela peut faire une grande différence de performance.

Cependant, ceci n’est qu’un “indice”, et le compilateur peut l’ignorer, et la plupart des compilateurs essaieront de “se connecter” même lorsque le mot clé n’est pas utilisé, dans le cadre des optimisations, là où 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 réalité sensiblement inférieur au code que le compilateur doit mettre en place 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 */}; 

Ignorer l'appel et le retour de la fonction réelle

Evidemment, ceci est un exemple pour montrer le point, pas un vrai morceau de code.

static réfère à la scope. En C, cela signifie que la fonction / variable ne peut être utilisée que dans la même unité de traduction.

Par défaut, une définition en ligne est uniquement valide dans l’unité de traduction actuelle.

Si la classe de stockage est extern , l’identificateur a un lien externe et la définition en ligne fournit également la définition externe.

Si la classe de stockage est static , l’identificateur a un lien 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 en cours, mais l’identificateur a toujours un lien externe et une définition externe doit être fournie dans une autre unité de traduction. Le compilateur est libre d’utiliser la définition inline ou external si la fonction est appelée dans l’unité de traduction actuelle.

Comme le compilateur est libre d’inclure (et de ne pas aligner) toute fonction dont la définition est visible dans l’unité de traduction en cours (et, grâce aux optimisations de temps de liaison, même dans différentes unités de traduction, le cela), pour des raisons pratiques, il n’y a pas de différence entre static définitions de fonctions static et static inline .

Le spécificateur en inline (comme la classe de stockage de register ) est uniquement un indice de compilation et le compilateur est libre de l’ignorer complètement. Les compilateurs non optimisés conformes aux normes doivent uniquement respecter leurs effets secondaires, et l’optimisation des compilateurs effectuera ces optimisations avec ou sans indications explicites.

inline et register ne sont cependant pas inutiles, car ils indiquent au compilateur de lancer des erreurs lorsque le programmeur écrit du code qui rendrait impossible l’optimisation: une définition inline externe ne peut pas faire référence à des identificateurs avec un lien interne (ceux-ci ne unité de traduction) ou définir des variables locales modifiables avec une durée de stockage statique (car elles ne partageraient pas d’états entre unités de traduction), et vous ne pouvez pas prendre d’adresse de variables qualifiées par un register .

Personnellement, j’utilise la convention pour marquer aussi static définitions de fonctions static dans les en-têtes, car la principale raison de placer des définitions de fonctions dans des fichiers d’en-tête est de les rendre inline.

En général, je n’utilise que static inline définitions de fonctions static inline et static const en plus des déclarations extern dans les en-têtes.

Je n’ai jamais écrit de fonction en inline avec une classe de stockage différente de la static .

D’après mon expérience avec GCC, je sais que static static inline static et static inline diffère de la façon dont le compilateur émet des avertissements sur les fonctions inutilisées. Plus précisément, lorsque vous déclarez static fonction static et qu’elle n’est pas utilisée dans l’unité de traduction en cours, le compilateur génère un avertissement sur la fonction inutilisée, mais vous pouvez empêcher cet avertissement en le transformant en static inline .

Ainsi, j’ai tendance à penser que le static devrait être utilisé dans les unités de traduction et bénéficier de vérifications supplémentaires que le compilateur fait pour trouver les fonctions inutilisées. Et static 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 liens externes) sans émettre d’avertissements.

Malheureusement, je ne trouve aucune preuve de cette logique. Même à partir de la documentation GCC, je n’ai pas pu conclure que l’ inline inhibe les avertissements de fonction inutilisés. J’apprécierais si quelqu’un partagerait des liens à la description de cela.

Une différence qui n’est pas au niveau du langage mais au niveau d’implémentation populaire: certaines versions de gcc suppriment par défaut static inline fonctions static inline non référencées, mais conservent static fonctions static même si elles ne sont pas référencées. Je ne suis pas sûr de savoir à quelles versions cela s’applique, mais d’un sharepoint vue pratique, cela signifie qu’il peut être judicieux de toujours utiliser inline pour static fonctions static dans les en-têtes.

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)

Donc, static inline signifie la fonction inline qui ne peut être utilisée que dans ce fichier.

MODIFIER:

L’unité de compilation devrait être The Translation Unit