Qu'est-ce que l'utilisation de la `inline` mot-clé dans C?
J'ai lu à plusieurs questions dans stackoverflow sur inline
en C, mais ne suis toujours pas clair à ce sujet.
static inline void f(void) {}
a pas de différence pratique avecstatic void f(void) {}
.inline void f(void) {}
en C ne fonctionne pas comme le C++ façon. Comment ça marche dans la C?- Ce qui ne fait
extern inline void f(void);
faire?
Je n'ai jamais vraiment trouvé une utilisation de la inline
mot-clé dans mes programmes en C, et quand je vois ce mot-clé dans d'autres gens du code, il est presque toujours static inline
, dans lequel je ne vois pas de différence avec juste static
.
- "Qu'est-ce que l'utilisation de la
inline
mot-clé dans le C?" – rien. - Cette question donne la réponse à tous vos doutes ...stackoverflow.com/questions/1759300/...
Vous devez vous connecter pour publier un commentaire.
Note: quand je parle de
.c
fichiers et.h
fichiers dans cette réponse, je suppose que vous avez jeté votre code correctement, c'est à dire.c
uniquement les fichiers comprennent.h
fichiers. La distinction est qu'un.h
fichier peut être inclus dans plusieurs unités de traduction.En ISO C, c'est correct. Ils sont identiques dans les comportements (en supposant que vous n'avez pas re-déclarer différemment dans le même TU bien sûr!) le seul effet pratique peut être à cause du compilateur d'optimiser différemment.
Ceci est expliqué par cette réponse et aussi ce fil.
En ISO C et C++, vous pouvez utiliser librement
inline void f(void) {}
dans les fichiers d'en-tête -- quoique pour des raisons différentes!En ISO C, il ne fournit pas une définition externe à tous. En ISO C++ il fournit une définition externe; cependant, C++ a une règle supplémentaire (qui C ne fait pas), que s'il y a plusieurs des définitions externes d'un
inline
fonction, le compilateur trie et sélectionne l'un d'entre eux.extern inline void f(void);
dans un.c
fichier dans ISO C est destiné à être couplé avec l'utilisation deinline void f(void) {}
dans les fichiers d'en-tête. Il provoque le définition externe de la fonction d'être émis en ce que l'unité de traduction. Si vous ne faites pas cela, alors il n'existe pas de définition externe, et de sorte que vous pouvez obtenir une erreur de lien (il n'est pas précisé si un appel particulier def
des liens à l'extérieur de la définition ou non).En d'autres termes, dans la norme ISO C, vous pouvez sélectionner manuellement où la définition externe va, ou de supprimer la définition externe entièrement à l'aide
static inline
partout; mais dans la norme ISO C++ le compilateur choisit si et où une définition externe irait.Dans C de GNU, les choses sont différentes (plus sur ce ci-dessous).
Pour compliquer encore les choses, GNU C++ permet d'écrire
static inline
unextern inline
dans le code C++... je ne voudrais pas deviner ce que fait exactementDe nombreux programmeurs ne savent pas ce qu'ils font et viens de mettre sur pied quelque chose qui semble fonctionner. Un autre facteur est que le code que vous êtes en train de regarder pourrait avoir été écrit pour GNU C, pas ISO C.
Dans GNU C, plaine
inline
se comporte différemment de la norme ISO C. Il réellement émet un visible de l'extérieur de définition, afin d'avoir une.h
fichier avec un simpleinline
fonction inclus à partir de deux unités de traduction provoque un comportement indéterminé.Donc, si le programmeur veut pour l'alimentation de l'
inline
indicateur d'optimisation en C de GNU, puisstatic inline
est nécessaire. Depuisstatic inline
fonctionne dans les deux ISO C et C de GNU, il est naturel que les gens finissent par s'installer pour que et de voir qu'il est apparu à travailler sans donner erreurs.La différence est juste dans l'intention de fournir une vitesse-sur-optimisation de la taille du conseil pour le compilateur. Avec les compilateurs modernes ce qui est superflu.
extern inline void f(void);
dans un .c fichier est destiné à être couplé avec l'utilisation destatic inline void f(void) {}
dans les fichiers d'en-tête". Ne devriez-vous pas supprimer lestatic
?extern
déclaration est inutile si je rencontre les exigences d'une ligne de définition?static
; je re-lire tout à l'heure et réalisé l'un de l'autre canonique réponses avaient la méconnaissent. "Il n'est pas précisé si l'appel à la fonction utilise la ligne de définition ou de la définition externe." ne s'applique qu'aux appels de fonctions inline avec une liaison externe, de sorte que les appels à unestatic inline
ne peut pas appeler l'définis à l'externe version. (En fait, cela me semble pour créer une barrière pour le compilateur de faire ensemble du programme d'optimisation)inline void f(void) {}
sansextern void f(void);
signifie qu'il est à la fois une ligne de définition et une fonction de liaison externe, de sorte que les appels à la fonction pourrait être liée à la définition externe au lieu de cela TU cylindres en ligne de définition.extern
déclaration, je ne peut pas obtenir de l'éditeur de liens erreurs si le compilateur utilise la ligne de définition, mais je ne reçois de l'éditeur de liens erreurs si le compilateur choisit la définition externe. J'ai juste testé avec gcc avec et sans optimisations. Sans optimisation, je reçois une erreur de l'éditeur de liens pour ne pas avoir une définition externe.Un code C peut être optimisé de deux manières: Pour la taille du Code et de Temps d'Exécution.
fonctions inline:
gcc.gnu.org dit,
Donc, il indique au compilateur de construire la fonction dans le code où il est utilisé avec l'intention d'améliorer les temps d'exécution.
Si vous déclarez des Petites fonctions comme le réglage/la compensation d'un drapeau ou d'un bit bascule qui sont effectuées à plusieurs reprises,
inline
, il peut faire une grande différence en termes de performances par rapport au temps, mais au détriment de la taille du code.non-static inline et Static inline
Faisant de nouveau référence à gcc.gnu.org,
extern inline?
De nouveau, gcc.gnu.org, tout est dit:
Cette combinaison de inline et extern a presque l'effet d'une macro. La façon de l'utiliser est de mettre une définition de fonction dans un fichier d'en-tête avec ces mots-clés, et remettre une copie de la définition (manque inline et externes) dans un fichier de bibliothèque. La définition dans le fichier d'en-tête provoque la plupart des appels à la fonction inline. Si toutes les utilisations de la fonction restent, ils se réfèrent à la seule copie dans la bibliothèque.
Pour résumer:
inline void f(void){}
,inline
définition n'est valable que dans le courant de l'unité de traduction.static inline void f(void) {}
Depuis la classe de stockage est
static
, de l'identifiant interne de la liaison et lainline
définition est invisible dans d'autres unités de traduction.extern inline void f(void);
Depuis la classe de stockage est
extern
, de l'identifiant liaison externe et la ligne de définition fournit également la définition externe.De 6.7.4 Fonction des prescripteurs en C11 spécifications
Il suggère compilateur que cette fonction est largement utilisé et des demandes de préférez la vitesse dans l'invocation de cette fonction. Mais avec moderne intelligent compilateur de ce qui peut être plus ou moins pertinent que les compilateurs peuvent décider si une fonction doit être incorporé et peut ignorer la ligne la demande des utilisateurs, car les compilateurs modernes peuvent très efficacement décider sur la façon d'appeler les fonctions.
Donc oui avec les compilateurs modernes, la plupart du temps aucun. Avec les compilateurs il y a pas pratique /observables sortie différences.
Une fonction qui est en ligne n'importe où doit être en ligne partout dans le C++ et l'éditeur de liens ne se plaint pas définition de plusieurs erreur (définition doit être la même).
Cela permettra d'offrir une liaison externe pour
f
. Parce que lef
peuvent être présents dans d'autres unité de compilation, le compilateur peut choisir différentes mécanisme d'appel pour accélérer les appels ou peut ignorer leinline
complètement.Une fonction où toutes les déclarations (y compris la définition) mentionnent en ligne et ne jamais extern.
Il doit y avoir une définition dans la même unité de traduction. La norme fait référence à ce qu'une ligne de définition.
Aucun objet autonome code est émis, de sorte que cette définition ne peut pas être appelé à partir d'une autre unité de traduction.
Dans cet exemple, toutes les déclarations et les définitions use inline mais pas extern:
Ici est une référence qui peut vous donner plus de clarté sur la ligne des fonctions en C & également sur l'utilisation de inline & extern.
Comme un mot "Inline" dire "Dans" la "Ligne", en ajoutant ce mot-clé pour fonction affecte le programme lors de l'exécution , lorsqu'un programme est compilé ,le code écrit entrailles de la fonction est collé sous l'appel de la fonction , comme les appels de fonction sont plus coûteux que le code en ligne, donc cela permet d'optimiser le code.
Donc,
static inline void f(void) {} et static void f(void) {} , dans ce mot-clé inline ne fait la différence dans l'exécution. Mais quand la fonction a trop de lignes de code, puis il ne sera pas l'effet de l'exécution.
Si vous ajoutez statique avant la fonction , fonction de la durée de vie est la durée de vie de l'ensemble du programme. Et que la fonction d'usage est restreint à ce fichier uniquement.
Pour connaître extern vous pouvez vous référer à Les effets du mot-clé extern sur les fonctions C
inline
mot-clé a été ajoutée à compilateurs (bien avant le premier C standard), qui a été son intention. Mais sa signification et son utilisation a beaucoup changé depuis.