Pourquoi "extern const int n;" ne fonctionne-t-il pas comme prévu?

Mon projet se compose de seulement deux fichiers source:

A.cpp:

const int n = 8;

B.cpp:

extern const int n;

int main()
{
    // error LNK2001: unresolved external symbol "int const n" (?n@@3HB)
    int m = n; 
}

Je sais qu'il existe plusieurs méthodes pour le faire fonctionner; cependant, je me demande juste pourquoi cela ne fonctionne pas?

26
demandé sur xmllmx 2013-02-15 16:24:32

5 réponses

C'est parce que const implique une liaison interne par défaut, donc votre "définition" n'est pas visible en dehors de l'Unité de traduction où il apparaît.

Dans ce cas, de loin la meilleure solution est de mettre la déclaration (extern int const n;) dans un fichier d'en-tête, et incluez-le dans les deux a.cpp et b.cpp. Le lien est déterminé par le première déclaration que le compilateur voit, donc la définition ultérieure dans {[3] } aura le lien (externe) correct.

Vous pouvez également forcer la liaison dans le définition:

extern int const n = 8;

Malgré le extern, c'est toujours une définition; tout avec un initialiseur en dehors d'une définition de classe est une définition.

45
répondu James Kanze 2013-02-15 12:38:15

const et les variables constexpr en C++ ont une liaison interne (et ne sont donc pas accessibles dans une autre unité de compilation) si elles ne sont pas également déclarées extern (soit dans la définition, soit dans une déclaration précédente).

En C, ce n'est pas le cas (eh bien C n'a pas constexpr) donc votre code est valide, et plus vous pouvez mettre extern sur une définition.

Donc, si vous voulez écrire du code qui est à la fois C et c++ (et les deux déclarations devraient probablement provenir du même en-tête que James pointed sortie):

// a.cpp
extern const int n;
const int n = 8;

// b.cpp
extern const int n;

int main()
{

    int m = n; 
}

Si vous ne le faites pas

// a.cpp
extern const int n = 8;

Est également possible

5
répondu AProgrammer 2013-02-15 12:47:02

Déclarer externe dans a.cpp et il suffit d'utiliser sans extern dans b.cpp:

A. h

extern const int n ;

A.cpp

#include "a.h"
...
const int n= 8

B.cpp:

#include "a.h"
...


int main()
{        
    int m = n; 
}
2
répondu Gjordis 2013-02-15 12:36:01

To share a const object among multiple files, you must define the variable as extern.

To define a single instance of a const variable, we use the keyword extern on both its definition and declaration(s):

A partir de ces règles, il vous suffit d'ajouter le mot clé extern dans votre définition. vous l'avez déjà dans la déclaration.

2
répondu Arpit 2013-02-15 12:44:06

Si les autres réponses ici ne font pas l'affaire, il se peut que vous ayez vos définitions dans différents espaces de noms... si la compilation passe et que vous obtenez une erreur undefined symbol linker:

  • Vérifiez l'espace de noms du symbole indéfini; c'est l'espace de noms effectif pour la déclaration extern const int n.
  • assurez-vous que c'est votre espace de noms efficace où vous faites la définition const int n = 8.
1
répondu einpoklum 2014-04-26 16:50:54