161 votes

Pourquoi les fonctions en ligne C ++ sont-elles dans l'en-tête?

NB Ce n'est pas une question sur la façon d'utiliser les fonctions inline ou comment ils fonctionnent, pourquoi ils sont fait de la façon dont ils sont.

La déclaration d'une fonction membre de classe n'a pas besoin de définir une fonction en tant que inline, c'est seulement la mise en œuvre effective de la fonction. Par exemple, dans le fichier d'en-tête:

struct foo{
    void bar(); // no need to define this as inline
}

Alors pourquoi ne inline mise en œuvre d'une des classes de fonction ont à être dans le fichier d'en-tête? Pourquoi ne puis-je pas mettre la fonction en ligne de l' .cpp le fichier? Si je où pour essayer de mettre la ligne de définition dans l' .cpp le fichier j'ai une erreur du genre:

error LNK2019: unresolved external symbol 
"public: void __thiscall foo::bar(void)"
(?bar@foo@@QAEXXZ) referenced in function _main 
1>C:\Users\Me\Documents\Visual Studio 2012\Projects\inline\Debug\inline.exe 
: fatal error LNK1120: 1 unresolved externals

167voto

Charles Bailey Points 244082

La définition de l' inline fonction n'a pas à être dans un fichier d'en-tête, mais, en raison de la définition de la règle pour les fonctions inline, une définition identique de la fonction doit exister dans chaque unité de traduction qui l'utilise.

Le plus simple pour y parvenir est d'adopter la définition dans un fichier d'en-tête.

Si vous voulez mettre la définition d'une fonction dans un fichier source unique, alors vous ne devriez pas déclarer inline. Une fonction non déclarée inline ne signifie pas que le compilateur ne peut pas inline de la fonction.

Si vous devez déclarer une fonction inline ou pas, est habituellement un choix que vous devez faire en fonction de la version de la définition des règles , il est logique pour vous de suivre; ajouter de l' inline puis d'être limité par les contraintes de peu de sens.

149voto

jalf Points 142628

Il y a deux façons de le regarder:

  1. Inline fonctions sont déclarées dans l'en-tête, car, pour inline appel de la fonction, le compilateur doit être en mesure de voir le corps de la fonction. Pour un naïf compilateur pour ce faire, le corps de la fonction doit être dans la même unité de traduction comme l'appel. (Un moderne compilateur peut optimiser à travers les unités de traduction, et donc un appel de fonction peut être incorporé même si la définition de la fonction est dans une autre unité de traduction, mais ces optimisations sont chers, ne sont pas toujours activé, et n'ont pas toujours été pris en charge par le compilateur)

  2. fonctions déclarées dans l'en-tête doit être marquée inline parce que sinon, chaque unité de traduction qui comprend l'en-tête contient une définition de la fonction, et l'éditeur de liens se plaignent de multiples définitions (violation de l'Une Définition de la Règle). L' inline mot-clé supprime cette, permettant à de multiples unités de traduction pour contenir (identiques) définitions.

Les deux explications vraiment se résument au fait que l' inline mot-clé n'est pas exactement ce que vous attendez.

Un compilateur C++ est libre d'appliquer les inline optimisation (remplacement d'un appel de fonction avec le corps de la fonction appelée, l'enregistrement de l'appel de coûts) tout le temps qu'il veut, tant qu'il ne modifie pas les comportements observables du programme.

L' inline mot-clé le rend plus facile pour le compilateur pour appliquer cette optimisation, en permettant la définition de la fonction pour être visible dans plusieurs unités de traduction, mais en utilisant le mot-clé ne veut pas dire que le compilateur a associé la fonction, et non pas en utilisant le mot-clé ne vous interdit pas de le compilateur à partir de la fonction inline.

32voto

xanatos Points 30513

C'est une limite du compilateur C++. Si vous mettez la fonction dans l'en-tête, tous les fichiers cpp où il peut être incorporé peut voir la "source" de votre fonction et de l'in-lining peut être fait par le compilateur. Sinon c'est l'alignement devra être faite par l'éditeur de liens (chaque fichier cpp est compilé dans un fichier obj séparément). Le problème, c'est qu'il serait beaucoup plus difficile de le faire dans l'éditeur de liens. Un problème similaire existe avec le "modèle" classes/fonctions. Ils ont besoin d'être instancié par le compilateur, parce que l'éditeur de liens auraient problème de l'instanciation (création d'une version spécialisée d'). Certains nouveau compilateur/linker peut faire deux "pass" compilation/liant où le compilateur fait une première passe, puis l'éditeur de liens ne de son travail et de l'appel au compilateur de résoudre les choses en suspens (inline/templates...)

16voto

Erik Points 38942

Le c++ inline mot-clé est trompeur, il ne signifie pas "inline cette fonction". Si une fonction est définie comme la ligne d'entrée, cela signifie simplement qu'il peut être défini à plusieurs reprises, tant que toutes les définitions sont égaux. Il est parfaitement légal pour une fonction marquée inline être un véritable fonction qui est appelée au lieu d'obtenir le code inline au point où il est appelé.

La définition d'une fonction dans un fichier d'en-tête est nécessaire pour les modèles, depuis par exemple basé sur un modèle de classe n'est pas vraiment une classe, c'est un modèle de classe que vous pouvez faire de multiples variations. Pour que le compilateur pour pouvoir par exemple faire un Foo<int>::bar() fonction lorsque vous utilisez les Foo modèle pour créer une classe Foo, de la définition de la Foo<T>::bar() doit être visible.

11voto

sbi Points 100828

La raison en est que le compilateur doit voir la définition pour pouvoir la déposer à la place de l'appel.

N'oubliez pas que C et C ++ utilisent un modèle de compilation très simpliste, dans lequel le compilateur ne voit toujours qu'une unité de traduction à la fois. (Cela échoue pour l'exportation, qui est la raison principale pour laquelle un seul fournisseur l'a réellement implémentée.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X