Question Le qualificatif en ligne provient du prototype ou de la définition?


Je ne suis pas tout à fait sûr de cela dans les normes. Disons que j'ai trois fichiers comme ceci:

foo.h

#include <iostream>

inline void foo();

void foo()
{
   std::cout << "Foo" << std::endl;
}

foo.cpp:

#include "foo.h"

void baz();

int main()
{
   baz();
   foo();
}

bar.cpp

#include "foo.h"

void baz()
{
   foo();
}

Maintenant, la définition de foo sera compilée dans les deux unités de compilation foo.o et bar.o. Si je le comprends bien, le fait d’avoir des fonctions intégrées évitera la collition de l'éditeur de liens. G ++ compilé et lie cela très bien, mais avec Clang ++ 2.8, j'obtiens cette erreur:

/tmp/cc-7RdmYP.o: In function `foo()':
bar.cpp:(.text+0x50): multiple definition of `foo()'
/tmp/cc-LW3id3.o:foo.cpp:(.text+0x50): first defined here
collect2: ld returned 1 exit status

Il semble que Clang ++ ne voit pas void foo() comme une fonction intégrée. Cela fonctionne cependant bien lorsque j'ajoute également à la définition.

Dois-je ajouter en ligne à void foo() aussi bien ici pour le voir comme une fonction intégrée, ou est-ce un bug de clang ++?


11
2018-02-07 18:21


origine


Réponses:


C ++ 0X draft N3225 dit dans 7.1.2 Function specifiers:

  • clause 2: A function declaration with an inline specifier declares an inline function
  • clause 4: An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case. 

Donc, pour moi, il semblerait que gcc ait raison, mais il y a toujours une (faible) chance que les choses soient (sont?) Différentes en C ++ 03.


2
2018-02-07 19:31



Il se peut que votre clang utilise la sémantique en ligne C99. En C99, si l'une de vos fonctions n'utilise pas "inline" ou inclut "extern", la définition est une "définition externe", qui ne peut apparaître qu'une seule fois dans le programme. Voir inline in C99.

En C ++, votre programme est correct. Dans Clang SVN, ce bogue a été corrigé et votre programme devrait fonctionner correctement.


4
2018-02-08 21:47



Je crois que l'intention de la norme a toujours été de permettre la création d'une fonction inline en ayant au moins une déclaration incluant le inline spécificateur, mais il y avait une certaine incertitude quand il était trop tard pour ajouter le premier inline déclaration. Était après la définition trop tard ou après le premier appel?

Mon raisonnement est double: tout d’abord, les exemples du 7.1.1, bien que non normatifs et portant principalement sur les spécificateurs de classe de stockage, suggèrent que inline n'est pas requis sur chaque déclaration.

Deuxièmement, ce rapport de défaut DR 317 à partir de 2001 (voté en 2005) qui ajoute "Si la définition d'une fonction apparaît dans une unité de traduction avant sa première déclaration en ligne, le programme est mal formé". phrase. Il ressort clairement de la conversation qu’il était prévu que inline n'est pas requis sur chaque déclaration, en particulier dans le cas d'une fonction membre définie explicitement inline mais en dehors du corps de la classe où la déclaration originale n'avait pas une explicite inline.

(Ce rapport de défaut contient également mon mantra inline est "plus qu'un indice".)

Bien sûr, dès qu’une fonction avec un lien externe est une fonction en ligne en raison d'une ou plusieurs déclarations, y compris la inline spécificateur dans une unité de traduction, il doit être déclaré inline dans toutes les unités de traduction conformément au reste du paragraphe 7.1.2 / 4.

Dans l'exemple de la question, je crois que l'intention est que foo est une fonction en ligne et qu'il s'agit d'un code valide, même si le texte normatif de la norme me semble moins clair qu'il pourrait l'être.


1
2018-02-07 22:10



Vous devez utiliser inline dans les deux endroits


0
2018-02-07 18:53