Por que “extern const int n;” não funciona como esperado?

Meu projeto consiste em apenas dois arquivos de origem:

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; } 

Eu sei que existem vários methods para fazer isso funcionar; no entanto, eu só me pergunto por que isso não funciona?

É porque const implica binding interna por padrão, então sua “definição” não é visível fora da unidade de tradução onde aparece.

Nesse caso, de longe, a melhor solução é colocar a declaração ( extern int const n; ) em um arquivo de header e incluí-la em a.cpp e b.cpp . A binding é determinada pela primeira declaração que o compilador vê, então a definição posterior em a.cpp terá a binding correta (externa).

Alternativamente, você pode forçar a binding na definição:

 extern int const n = 8; 

Apesar do extern , isso ainda é uma definição; qualquer coisa com um inicializador fora de uma definição de class é uma definição.

constexpr variables const e constexpr em C ++ têm binding interna (e, portanto, não são acessíveis em outra unidade de compilation), se não forem também declaradas extern (na definição ou em uma declaração anterior).

Em C, não é o caso (bem, C não tem constexpr ), então seu código é válido, e mais você pode colocar extern em uma definição.

Então, se você quiser escrever código que seja C e C ++ (e as duas declarações provavelmente virão do mesmo header que James apontou):

 // a.cpp extern const int n; const int n = 8; // b.cpp extern const int n; int main() { int m = n; } 

se você não

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

também é possível

Declare-o extern em a.cpp e apenas use sem extern em b.cpp:

ah

 extern const int n ; 

a.cpp

 #include "ah" ... const int n= 8 

b.cpp:

 #include "ah" ... int main() { int m = n; } 

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 dessas regras, você só precisa adicionar a palavra-chave extern à sua definição. você já tem isso em declaração.

Se as outras respostas aqui não resolverem o problema, pode ser que você tenha suas definições em namespaces diferentes … se a compilation passar e você receber um erro de vinculador de undefined symbol :

  • verifique o namespace do símbolo indefinido; esse é o namespace efetivo para a declaração extern const int n .
  • Assegure-se de que seu namespace efetivo faça a definição de const int n = 8 .