web-dev-qa-db-fra.com

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

Mon projet se compose de seulement deux fichiers sources:

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?

27
xmllmx

C'est parce que const implique un lien interne par défaut, donc votre "définition" n'est pas visible en dehors de l'unité de traduction où elle apparaît.

Dans ce cas, la meilleure solution est de loin de mettre la déclaration (extern int const n;) dans un fichier d'en-tête et l'inclure dans les deux a.cpp et b.cpp. La liaison est déterminée par la première déclaration que le compilateur voit, donc la dernière définition dans a.cpp aura la liaison (externe) correcte.

Alternativement, vous pouvez forcer le lien dans la définition:

extern int const n = 8;

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

50
James Kanze

const et constexpr les variables en C++ ont un lien 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 dans une déclaration précédente).

En C, ce n'est pas le cas (enfin C n'a pas constexpr) donc votre code est valide, et en 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 l'a souligné):

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

// b.cpp
extern const int n;

int main()
{

    int m = n; 
}

si tu ne le fais pas

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

est également possible

6
AProgrammer

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):

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

2
Arpit

Déclarez-le extern dans a.cpp et utilisez simplement 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
Gjordis

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 réussit, et vous obtenez un undefined symbol erreur de l'éditeur de liens:

  • vérifier l'espace de noms du symbole non défini; c'est l'espace de noms efficace pour le extern const int n déclaration.
  • assurez-vous que c'est votre espace de noms efficace où vous créez const int n = 8 définition.
1
einpoklum