Question

Si l'on définit une fonction membre dans la définition de la classe elle-même, est-il nécessairement en ligne traitée ou est-ce simplement une demande au compilateur qu'elle peut ignorer.

Était-ce utile?

La solution

Oui, les fonctions qui sont définies dans un corps de classe sont implicitement inline.

(Comme avec d'autres fonctions déclarées inline cela ne signifie pas que le complier doit effectuer l'expansion en ligne dans des endroits où la fonction est appelée, elle permet seulement les relaxations autorisés de la « une règle de définition », combinée à l'exigence selon laquelle une définition doit être incluse dans toutes les unités de traduction où la fonction est utilisée.)

Autres conseils

Comme indiqué par d'autres, une méthode définie dans une classe est automatiquement demandée en ligne. Il est utile de comprendre pourquoi.

Supposons que ce n'était pas. Il faudrait générer du code pour une telle fonction, et partout où il est appelé, un saut à l'instruction de sous-programme devrait faire référence à l'emplacement, via l'éditeur de liens.

class A {
public:
  void f() { ... your code ... }
};

Chaque fois que ce code est vu, si ce n'est pas en ligne, le compilateur ne peut que supposer qu'il doit être généré, il générerait un symbole. Supposons qu'il était comme ceci:

A__f_v:

Si ce symbole était global, alors si vous est arrivé d'inclure ce code de classe plusieurs fois dans différents modules, vous auriez une erreur de symbole défini se multiplient au moment de la liaison. Il ne peut donc être globale. , Il est au lieu fichier local.

Imaginez que vous incluez le fichier d'en-tête ci-dessus dans un certain nombre de modules. Dans chacun, il va générer une copie locale de ce code. Ce qui est mieux que de ne pas la compilation du tout, mais vous obtenez plusieurs copies du code lorsque vous avez vraiment besoin d'un seul.

Il en résulte la la conclusion suivante: si votre compilateur ne va pas inline une fonction, vous êtes beaucoup mieux déclarer quelque part une fois, et ne demande pas à être inline

.

Malheureusement, ce qui est et n'est pas en ligne ne sont pas portables. Elle est définie par l'auteur du compilateur. Une bonne règle de base est de toujours faire tout le revêtement, en particulier toutes les fonctions qui appellent eux-mêmes juste une fonction, en ligne, que vous retirez les frais généraux. Tout en dessous de trois lignes de code linéaire est presque certainement ok. Mais si vous avez une boucle dans le code, la question est de savoir si le compilateur lui permettra en ligne, et plus au point, le montant des prestations que vous verriez même si elle a fait ce que vous voulez.

considérer ce code en ligne:

inline int add(int a, int b) { return a + b; }

Il est non seulement presque aussi petit que le prototype serait en code source, mais le langage assembleur généré par le code en ligne est plus petit que l'appel à une routine serait. Donc, ce code est plus petit et plus rapide.

Et, si vous arrive d'être dans le passage des constantes:

int c= add(5,4);

Il est résolu au moment de la compilation et il n'y a pas de code.

Dans gcc, j'ai récemment remarqué que même si je ne suis pas le code en ligne, si elle est locale à un fichier, ils sneakily inline toute façon. Il est seulement si je déclare la fonction dans un module source distincte ne permet pas d'optimiser loin l'appel.

À l'autre extrémité du spectre, supposons que vous demandez en ligne sur un morceau de ligne 1000 du code. Même si votre compilateur est assez bête pour aller avec elle, la seule chose que vous enregistrez est l'appel lui-même, et le coût est que chaque fois que vous l'appelez, le compilateur doit coller tout ce code. Si vous appelez cela n fois le code , votre code se développe par la taille de la routine * n. Donc, quoi que ce soit plus de 10 lignes est à peu près ne vaut pas inline, sauf pour le cas particulier où il est seulement appelé un très petit nombre de fois. Un exemple de cela pourrait être dans une méthode privée appelée par seulement deux autres.

Si vous demandez si elle exécute souvent un petit nombre de fois à inline une méthode contenant une boucle, il est logique. Mais considérez une boucle qui itère un million de fois. Même si le code est inline, le pourcentage du temps passé dans l'appel est minuscule. Donc, si vous avez des méthodes avec des boucles en elle, qui ont tendance à être plus grand de toute façon, ceux qui valent la suppression du fichier d'en-tête parce qu'ils a) auront tendance à être rejetée comme ligne par le compilateur et b), même si elles ont été inline, sont généralement ne va pas fournir un avantage

Il est nécessairement traité par le compilateur comme une demande de ligne - qui peut ignorer. Il y a quelques idiomes pour définir certaines fonctions dans l'en-tête (par exemple vides de Destructeurs virtuels) et quelques définitions d'en-tête nécessaires (fonctions de modèle), mais autre que voir GotW # 33 pour plus d'informations.

Certains ont noté que le compilateur peut vous jamais demandé même les fonctions inline à, mais je ne suis pas sûr que cela irait à l'encontre du but de demander à inline une fonction.

Il est en effet inline -. Mais toute demande en ligne peut être ignorée par le compilateur

Il est une demande au compilateur qu'il peut ignorer.

La norme de l'ISO 2003 C dit

  

7.1.2 / 2 Une déclaration de fonction (8.3.5, 9.3, 11.4) avec une ligne   spécificateur déclare une ligne   une fonction. Le prescripteur en ligne   indique la mise en œuvre qui   substitution de la fonction en ligne   corps au point d'appel doit être   préféré à la fonction appel habituelle
  mécanisme. Une mise en œuvre n'est pas   nécessaire pour effectuer cette ligne
  substitution au point d'appel;   Cependant, même si cette ligne
  la substitution est omis, l'autre   règles pour les fonctions inline définies   par 7.1.2 toujours être respectées.

     

7.1.2 / 3 Une fonction définie dans une définition de classe est une
en ligne   une fonction. Le prescripteur en ligne doit   ne pas apparaître sur une fonction de la portée du bloc   déclaration.

     

7.1.2 / 4 Une fonction en ligne doit être définie dans chaque unité de traduction dans
  dont il est utilisé et a   exactement la même définition dans tous les
  cas (3.2). [Note: un appel à la   fonction en ligne peut être rencontrée
  avant sa-défi nition apparaît dans la   l'unité de traduction. ] Si une fonction   avec une liaison externe est déclarée   en ligne dans une unité traduc-tion, il   doit être déclarée en ligne dans tous les   unités de traduction dans lequel il   apparaît; n'est nécessaire de diagnostic. Un   fonction en ligne avec externe   lien doit avoir la même adresse   toutes les unités de traduction. statique   variable locale dans une
ligne extern   fonction se réfère toujours à la même   objet. Une chaîne dans un
  extern fonction en ligne est le même   objet différent traduction
  unités.

Il y a deux choses qui ne devraient pas être regroupés ensemble:

  1. Comment vous marquez une fonction comme étant en ligne: définir avec ligne en face de la signature ou la définir au point de déclaration;
  2. Qu'est-ce que le compilateur traitera un tel marquage en ligne:. Quelle que soit la façon dont vous avez marqué la fonction en ligne, elle sera traitée comme une demande par le compilateur
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top