Je comprends que c'est inline
en soi une suggestion pour le compilateur, et à sa discrétion, il peut ou non intégrer la fonction, et il produira également du code objet pouvant être lié.
Je pense que cela static inline
fait la même chose (peut ou non en ligne) mais ne produira pas de code d'objet pouvant être lié lorsqu'il est en ligne (car aucun autre module ne peut y être lié).
Où extern inline
s'inscrit-il dans l'image?
Supposons que je veuille remplacer une macro de préprocesseur par une fonction en ligne et exiger que cette fonction soit intégrée (par exemple, parce qu'elle utilise les macros __FILE__
et __LINE__
qui devraient résoudre pour l'appelant mais pas cette fonction appelée). Autrement dit, je veux voir une erreur de compilateur ou de l'éditeur de liens au cas où la fonction ne serait pas intégrée. Le extern inline
fait-il? (Je suppose que, si ce n'est pas le cas, il n'y a aucun moyen d'obtenir ce comportement autre que de s'en tenir à une macro.)
Existe-t-il des différences entre C ++ et C?
Existe-t-il des différences entre les différents fournisseurs et versions de compilateurs?
la source
extern inline
est soumise à la règle d'une définition unique, et c'est la définition. Mais si l'heuristique d'optimisation définie par l'implémentation suit la recommandation d'utiliser leinline
mot - clé comme une suggestion que "les appels à la fonction soient aussi rapides que possible" (ISO 9899: 1999 §6.7.4 (5),extern inline
compteJe crois que vous avez mal compris __FILE__ et __LINE__ sur la base de cette déclaration:
Il existe plusieurs phases de compilation, et le prétraitement est le premier. __FILE__ et __LINE__ sont remplacés au cours de cette phase. Ainsi, au moment où le compilateur peut considérer la fonction à insérer, elle a déjà été remplacée.
la source
On dirait que vous essayez d'écrire quelque chose comme ceci:
et en espérant que vous obtiendrez différentes valeurs imprimées à chaque fois. Comme Don le dit, vous ne le ferez pas, car __FILE__ et __LINE__ sont implémentés par le préprocesseur, mais en ligne est implémenté par le compilateur. Ainsi, où que vous appeliez printLocation, vous obtiendrez le même résultat.
La seule façon de faire fonctionner cela est de faire de printLocation une macro. (Oui je sais...)
la source
La situation avec inline, static inline et extern inline est compliquée, notamment parce que gcc et C99 définissent des significations légèrement différentes pour leur comportement (et probablement aussi C ++). Vous pouvez trouver des informations utiles et détaillées sur ce qu'ils font en C ici .
la source
Les macros sont votre choix ici plutôt que les fonctions en ligne. Une occasion rare où les macros dominent les fonctions en ligne. Essayez ce qui suit: J'ai écrit ce code "MACRO MAGIC" et cela devrait fonctionner! Testé sur gcc / g ++ Ubuntu 10.04
Pour plusieurs fichiers, définissez ces macros dans un fichier d'en-tête distinct, y compris le même dans chaque fichier c / cc / cxx / cpp. Dans la mesure du possible, préférez les fonctions en ligne ou les identifiants const (selon le cas) aux macros.
la source
Au lieu de répondre "que fait-il?", Je réponds "comment faire ce que je veux?" Il existe 5 types d'inlining, tous disponibles dans GNU C89, C99 standard et C ++:
toujours en ligne, sauf si l'adresse est prise
Ajoutez
__attribute__((always_inline))
à n'importe quelle déclaration, puis utilisez l'un des cas ci-dessous pour gérer la possibilité que son adresse soit prise.Vous ne devriez probablement jamais l'utiliser, sauf si vous avez besoin de sa sémantique (par exemple pour affecter l'assemblage d'une certaine manière, ou pour l'utiliser
alloca
). Le compilateur sait généralement mieux que vous si cela en vaut la peine.en ligne et émettre un symbole faible (comme C ++, alias "faites que ça marche")
Notez que cela laisse un tas de copies du même code traîner, et l'éditeur de liens en choisit une arbitrairement.
en ligne, mais n'émet jamais de symbole (laissant des références externes)
émettre toujours (pour un TU, pour résoudre le précédent)
La version suggérée émet un symbole faible en C ++, mais un symbole fort dans l'un ou l'autre des dialectes de C:
Ou vous pouvez le faire sans l'indice, qui émet un symbole fort dans les deux langues:
En règle générale, vous savez quelle langue est votre TU lorsque vous fournissez les définitions, et vous n'avez probablement pas besoin de beaucoup d'insertion.
en ligne et émettre dans chaque TU
Pour tous ceux-ci sauf celui-
static
là, vous pouvez ajouter unevoid foo(void)
déclaration ci-dessus. Cela facilite la "meilleure pratique" d'écrire des en-têtes propres, puis de#include
créer un fichier séparé avec les définitions en ligne. Ensuite, si vous utilisez des lignes en ligne de style C,#define
une macro différemment dans une unité TU dédiée pour fournir les définitions hors ligne.N'oubliez pas
extern "C"
si l'en-tête peut être utilisé à la fois en C et en C ++!la source
nm
équivalent.