Question

J'ai cette situation:

// Test.h
extern const int param;
class Test
{
private:
    int i;
public:
    int foo();
};

et

// Test.cpp
#include "Test.h"
int Test::foo() { return param*10; }

et

// core.h
#include "Test.h"
const int param = 1; // should have internal linkage later in core.cpp
int do_stuff ();

et

// core.cpp
#include "core.h"
int do_stuff () { Test obj; return obj.foo(); }
int main() { return do_stuff(); }

Cependant, il n'y a pas d'erreur de liaison.Comment l'éditeur de liens voit-il pour Test.cpp le const int param qui est via core.h défini dans core.cpp ayant un lien interne (par défaut pour les définitions const) ?

Quand je réécris core.h comme ceci (change deux lignes) :

// core.h
const int param = 1;
#include "Test.h"
int do_stuff ();

il y a une erreur de l'éditeur de liens pour manquant param.Et puis, quand je le change comme ça :

// core.h
extern const int param = 1;
#include "Test.h"
int do_stuff ();

tout fonctionne à nouveau.

J'ai pensé que peut-être dans la situation d'origine, il y avait une intégration automatique de la classe Test dans core.cpp, de sorte que Test.cpp n'existe pas et que tout le code est dans core.cpp, pour que tout fonctionne.Mais pourquoi cela devrait-il alors dépendre de la modification des deux lignes dans core.h ?

Était-ce utile?

La solution

Votre hypothèse concernant les liens internes pour les définitions const n'est pas toujours vraie.Voir la section standards 3.5 Program linkage, p.3 (je cite N3690) :

Un nom ayant une portée d'espace de noms (3.3.6) a un lien interne s'il s'agit du nom de

  • une variable, une fonction ou un modèle de fonction explicitement déclaré statique ;ou,

  • une variable non volatile qui est explicitement déclarée const ou constexpr et ni explicitement déclarée extern ni précédemment déclaré comme ayant un lien externe;ou

  • un membre de données d’un syndicat anonyme.

Donc pour le premier cas param a un lien externe et tout va bien.

Pour le deuxième cas, il existe un lien interne param dans core.cpp, mais il y en a un autre déclaré uniquement param avoir un lien externe mais pas de définition.

Dans le troisième cas, il y a un param encore.

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