web-dev-qa-db-fra.com

Quelle est la différence entre les fonctions "statique" et "statique en ligne"?

OMI à la fois rendre la fonction pour avoir une portée de l'unité de traduction uniquement.

Quelle est la différence entre les fonctions "statique" et "statique en ligne"?

Pourquoi inline devrait-il être placé dans un fichier d’en-tête et non dans .c fichier?

112
new_perl

inline indique au compilateur de tenter de 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, cela peut faire une grande différence en termes de performances.

Cependant, il ne s'agit que d'un "indice" et le compilateur peut l'ignorer, et la plupart des compilateurs essaieront de "s'inscrire" 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 étroite effectuera un appel de fonction à chaque itération, et le contenu de la fonction est en réalité nettement inférieur au code que le compilateur doit mettre pour effectuer l'appel. inline va essentiellement demander 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 de fonction et le retour

Évidemment, ceci 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.

95
littleadv

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

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

Si la classe de stockage est static, l'identifiant 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 une liaison 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 inline ou externe si la fonction est appelée dans l'unité de traduction en cours.

Comme le compilateur est libre d’inscrire inline (et de ne pas inline) 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 en compte cela), dans la plupart des cas, il n'y a pas de différence entre static et static inline définitions de fonctions.

Le spécificateur inline (comme la classe de stockage register) n'est qu'un indicateur du compilateur, et le compilateur est libre de l'ignorer complètement. Les compilateurs non optimisateurs conformes aux normes doivent uniquement prendre en compte leurs effets secondaires, et l'optimisation des compilateurs effectuera ces optimisations avec ou sans conseils explicites.

inline et register ne sont toutefois pas inutiles, car ils ordonnent au compilateur de générer des erreurs lorsque le programmeur écrit un code rendant les optimisations impossibles: Une définition externe inline peut ' t identifiants de référence avec liaison 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 les adresses de register- variables qualifiées.

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

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

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

72
Christoph

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

Ainsi, j'ai tendance à penser que static devrait être utilisé dans les unités de traduction et tirer parti des possibilités supplémentaires du compilateur de chèques pour trouver des fonctions inutilisées. Et static inline devrait être utilisé dans les fichiers d’en-tête pour fournir des fonctions qui peuvent être alignées (en raison de l’absence de liaison externe) sans émettre d’avertissements.

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

16
ony

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 désigne la fonction en ligne utilisable uniquement dans ce fichier.

EDIT:

L'unité de compilation doit être L'unité de traduction

5
shengy

Une différence n’est pas au niveau de la langue mais au niveau de l’implémentation populaire: certaines versions de gcc supprimeront par défaut les fonctions static inline Non référencées, mais conserveront les fonctions simples static 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 que ce peut être une bonne idée de toujours utiliser inline pour les fonctions static dans les en-têtes.

5
R..