Question

Quand dois-je écrire le mot-clé pour inline de fonction / méthode en C ++?

Après avoir vu des réponses, des questions liées:

  • Quand dois-je pas écrire le mot-clé 'en ligne' pour une fonction / méthode en C ++?

  • Quand le compilateur sait pas quand faire une fonction / méthode 'en ligne'?

  • Est-il important si une application est multithread quand on écrit 'en ligne' pour une fonction / méthode?

Était-ce utile?

La solution

Oh man, un de mes marottes.

inline est plus comme static ou extern qu'une directive indiquant le compilateur inline vos fonctions. extern, static, inline sont des directives liaison, utilisées presque exclusivement par l'éditeur de liens, et non le compilateur.

On dit que des notes de inline au compilateur que vous pensez que la fonction doit être inline. Cela peut être vrai en 1998, mais une décennie plus tard, le compilateur n'a pas besoin de ces conseils. Sans parler de l'homme sont généralement mauvais en ce qui concerne l'optimisation du code, de sorte que la plupart des compilateurs à plat ignorent le « soupçon ».

  • static - le nom de la variable / fonction ne peut pas être utilisé dans d'autres unités de traduction. Linker a besoin pour vous assurer qu'il ne se sert pas accidentellement une variable statique définie / fonction à partir d'une autre unité de traduction.

  • extern - utiliser ce nom de variable / fonction dans cette unité de traduction, mais ne se plaignent pas si elle est pas définie. L'éditeur de liens trierai et assurez-vous tout le code qui a essayé d'utiliser un symbole extern a son adresse.

  • inline - cette fonction sera définie dans plusieurs unités de traduction, ne vous inquiétez pas. L'éditeur de liens doit assurer que toutes les unités de traduction utilisent une seule instance de la variable / fonction.

Remarque: En général, déclarant modèles inline est inutile, car ils ont la sémantique de liaison de inline déjà. Cependant, la spécialisation explicite et instanciation des modèles exigent inline à utiliser.


réponses spécifiques à vos questions:

  •   

    Quand dois-je écrire le mot-clé « en ligne » pour une fonction / méthode en C ++?

    Seulement quand vous voulez que la fonction à définir dans un en-tête. Plus exactement que lorsque la définition de la fonction peut apparaître dans plusieurs unités de traduction. Il est une bonne idée de définir les petits (comme dans une doublure) fonctions dans le fichier d'en-tête car il donne le compilateur plus d'informations pour travailler avec tout en optimisant votre code. Il augmente également le temps de compilation.

  •   

    Quand dois-je pas écrire le mot-clé « en ligne » pour une fonction / méthode en C ++?

    Ne pas ajouter de ligne juste parce que vous pensez que votre code fonctionnera plus rapidement si le compilateur inline il.

  •   

    Quand le compilateur sait pas quand faire une fonction / méthode « en ligne »?

    En général, le compilateur sera en mesure de faire mieux que vous. Cependant, le compilateur n'a pas l'option de code en ligne si elle ne dispose pas de la définition de la fonction. Dans le code optimisé au maximum généralement toutes les méthodes de private sont inline si vous le demandez ou non.

    En aparté pour éviter inline dans GCC, l'utilisation __attribute__(( noinline )) et dans Visual Studio, utilisez __declspec(noinline).

  •   

    Est-il important si une application est multithread quand on écrit « en ligne » pour une fonction / méthode?

    multithreading n'affecte pas inline en aucune façon.

Autres conseils

Je voudrais contribuer à toutes les grandes réponses dans ce fil avec un exemple convaincant pour disperser tout malentendu qui reste.

Étant donné deux fichiers sources, tels que:

  • inline111.cpp:

    #include <iostream>
    
    void bar();
    
    inline int fun() {
      return 111;
    }
    
    int main() {
      std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
      bar();
    }
    
  • inline222.cpp:

    #include <iostream>
    
    inline int fun() {
      return 222;
    }
    
    void bar() {
      std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
    }
    

  • Cas A:

    Compile :

    g++ -std=c++11 inline111.cpp inline222.cpp
    

    Sortie :

    inline111: fun() = 111, &fun = 0x4029a0
    inline222: fun() = 111, &fun = 0x4029a0
    

    Discussion :

    1. Même tu vous devriez avoir des définitions identiques de votre ligne fonctions, le compilateur C ne signale pas si ce n'est pas le cas (en fait, en raison de compilation séparée il n'a pas les moyens de le vérifier). Il est votre devoir de veiller à ce!

    2. Linker ne se plaint pas de Une règle Définition , comme fun() est déclarée comme inline. Cependant, parce que inline111.cpp est la première unité de traduction (qui appelle effectivement fun()) traitées par le compilateur, le compilateur instancie fun() sur son premier call-rencontre inline111 .cpp . Si le compilateur décide pas pour développer fun() sur son appel de partout ailleurs dans votre programme ( par exemple de inline222.cpp ), l'appel à fun() sera toujours liée à son instance produite à partir de inline111.cpp (l'appel à l'intérieur fun() inline222.cpp peut également produire une instance dans cette unité de traduction, mais il restera dissociées) . En effet, c'est évident d'après les impressions de &fun = 0x4029a0 identiques.

    3. Enfin, malgré la suggestion de inline au compilateur développer réellement la fun() one-liner, il ignore votre suggestion tout à fait, ce qui est clair, car fun() = 111 en les deux lignes.


  • Cas B:

    Compile (notez l'ordre inverse) :

    g++ -std=c++11 inline222.cpp inline111.cpp
    

    Sortie :

    inline111: fun() = 222, &fun = 0x402980
    inline222: fun() = 222, &fun = 0x402980
    

    Discussion :

    1. Cette affaire affirme ce qui a été discuté dans Cas A .

    2. Remarquez un point important, que si vous commentez l'appel réel à fun() inline222.cpp ( par exemple commenter cout-déclaration inline222.cpp complètement) puis, malgré l'ordre de compilation de vos unités de traduction, fun() sera instancié sur sa première rencontre d'appel inline111.cpp , ce qui impression pour cas B comme inline111: fun() = 111, &fun = 0x402980.


  • Affaire C:

    Compile (avis -O2) :

    g++ -std=c++11 -O2 inline222.cpp inline111.cpp
    

    ou

    g++ -std=c++11 -O2 inline111.cpp inline222.cpp
    

    Sortie :

    inline111: fun() = 111, &fun = 0x402900
    inline222: fun() = 222, &fun = 0x402900
    

    Discussion :

    1. Comme décrit ici , -O2 l'optimisation encourage le compilateur à développer réellement les fonctions qui peuvent être mis en ligne (Notez également que -fno-inline est default sans option d'optimisation). Comme il ressort de la outprint ici, le fun() a effectivement été en ligne étendu (selon sa définition dans ce particulier unité de traduction), ce qui entraîne deux différents impressions de fun(). Malgré cela, il y a encore une seule par exemple à l'échelle mondiale liée de fun() (tel que requis par la norme), comme il ressort de identiques &fun version imprimée.

Vous devez toujours inline explicitement votre fonction lorsque vous faites la spécialisation du modèle (si la spécialisation est dans le fichier .h)

1) De nos jours, à peu près jamais. Si c'est une bonne idée de inline une fonction, le compilateur fera sans votre aide.

2) tout le temps. Voir # 1.

(Sous la direction pour indiquer que vous avez cassé votre question en deux ...)

  

Quand dois-je pas écrire le mot-clé « en ligne » pour une fonction / méthode en C ++?

Si la fonction est définie dans le fichier .cpp, vous devez pas écrire le mot-clé.

  

Quand le compilateur sait pas quand faire une fonction / méthode « en ligne »?

Il n'y a pas cette situation. Le compilateur ne peut pas faire une ligne de fonction. Tout ce qu'il peut faire est de inline certains ou tous les appels à la fonction. Il ne peut pas le faire si elle n'a pas le code de la fonction (dans ce cas, l'éditeur de liens doit le faire si elle est capable de le faire).

  

Est-il important si une application est multithread quand on écrit « en ligne » pour une fonction / méthode?

Non, cela ne fait rien du tout.

  • Quand le compilateur sait pas quand faire une fonction / méthode « en ligne »?

Cela dépend du compilateur utilisé. Ne faites pas confiance aveuglément que de nos jours, les compilateurs savent mieux que les humains comment ligne et vous ne devriez jamais l'utiliser pour des raisons de performance, car il est la directive de liaison plutôt que d'optimisation soupçon. Je conviens que sont idéologiquement ces arguments corriger rencontre la réalité pourrait être une chose différente.

Après avoir lu plusieurs threads autour j'ai essayé par curiosité les effets de la ligne sur le code que je suis juste de travail et les résultats ont montré que je suis arrivé mesurable pour GCC speedup et pas jusqu'à la vitesse pour le compilateur Intel.

(Plus de détails: simulations mathématiques avec quelques fonctions essentielles définies en dehors des cours, GCC 4.6.3 (g ++ -O3), ICC 13.1.0 (ICPC -O3), en ajoutant en ligne aux points critiques causé + 6% avec le code speedup GCC ).

Donc, si vous êtes admissible à GCC 4.6 comme compilateur moderne, le résultat est que la directive en ligne est encore importante si vous écrivez des tâches intensives de CPU et de savoir où est exactement le goulot d'étranglement.

En réalité, à peu près jamais. Tout ce que vous faites est ce qui suggère que le compilateur faire une ligne de fonction donnée (par exemple, remplacer tous les appels à cette fonction / w son corps). Il n'y a aucune garantie, bien sûr: le compilateur peut ignorer la directive

.

Le compilateur fera généralement un bon travail de détection + optimisation des choses comme ça.

  

gcc par défaut n'inline aucune fonction lors de la compilation sans   optimisation activée. Je ne sais pas visual studio - deft_code

J'ai vérifié pour Visual Studio 9 (15.00.30729.01) en compilant avec / FACS et en regardant le code assembleur: Le compilateur produit appels à des fonctions membres sans optimisation activée dans debug mode . Même si la fonction est marquée avec __ forceinline , pas de code d'exécution en ligne est produit.

Vous voulez le mettre au début, avant que le type de retour. Mais la plupart ignorent Compilateurs. Si elle est définie, et il a un plus petit bloc de code, la plupart des compilateurs considèrent inline de toute façon.

Lors du développement et le débogage de code, laisser inline out. Il complique le débogage.

La principale raison de les ajouter est d'aider à optimiser le code généré. En général, cette espace de métiers a augmenté le code pour la vitesse, mais parfois inline permet d'économiser l'espace de code et le temps d'exécution.

Dépenser ce genre de réflexion sur l'optimisation des performances avant la fin de l'algorithme est optimisation prématurée .

Quand on doit inline:

1. Lorsque vous voulez éviter une surcharge des choses qui se produisent lorsque la fonction est appelée comme le passage de paramètres, le transfert de contrôle, le retour de commande etc.

fonction 2. doit être petit, souvent appelé et faire en ligne est vraiment avantageux car selon la règle 80-20, essayez de faire les ligne de fonction qui a un impact majeur sur la performance du programme.

Comme nous savons que ligne est juste une demande de compilateur semblable à enregistrer et il vous en coûtera au format de code objet.

Sauf si vous écrivez une bibliothèque ou avez des raisons particulières, vous pouvez oublier inline et utiliser optimisation lien temps à la place. Il supprime l'exigence selon laquelle une définition de fonction doit être dans un en-tête pour qu'il soit considéré pour inline dans toutes les unités de compilation, ce qui est précisément ce qui permet inline.

(Mais voir Y at-il raison pourquoi ne pas utiliser l'optimisation des temps de lien )

fonction C ++ en ligne est un concept puissant qui est couramment utilisé avec des classes. Si une fonction est en ligne, le compilateur place une copie du code de cette fonction à chaque point où la fonction est appelée au moment de la compilation.

Toute modification apportée à une fonction en ligne pourrait exiger que tous les clients de la fonction d'être recompilées, car le compilateur aurait besoin de remplacer tout le code une fois de plus il sinon continuer ancienne fonctionnalité.

Pour inline une fonction, placez le mot-clé en ligne avant le nom de la fonction et de définir la fonction avant que les appels sont effectués à la fonction. Le compilateur peut ignorer le qualificatif de ligne dans le cas où la fonction définie est supérieure à une ligne.

Une définition de fonction dans une définition de classe est une définition de fonction en ligne, même sans l'utilisation du prescripteur en ligne.

Voici un exemple, ce qui rend l'utilisation de fonction en ligne pour revenir maximum de deux nombres

#include <iostream>

using namespace std;

inline int Max(int x, int y) { return (x > y)? x : y; }

// Main function for the program
int main() {
   cout << "Max (100,1010): " << Max(100,1010) << endl;

   return 0;
}

Pour plus d'informations, voir .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top