2013-02-15 8 views
22

Il mio progetto è costituito da due soli file di origine:Perché "extern const int n;" non funziona come previsto?

a.cpp:

const int n = 8; 

b.cpp:

extern const int n; 

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

So che ci sono diversi metodi per farlo funzionare; tuttavia, mi chiedo solo perché non funziona?

+7

Provare a cambiare 'a.cpp' in extern const int n = 8;' AFAIK 'const' implica' static', anche se non lo so. – Pubby

+0

a.cpp ha bisogno di vedere la declinazione di n con la parola chiave extern? –

+0

Non ci hai detto che link e come ... – PlasmaHH

risposta

39

È perché const implica il collegamento interno per impostazione predefinita, quindi la "definizione" non è visibile al di fuori dell'unità di traduzione dove appare.

In questo caso, di gran lunga la soluzione migliore è quella di inserire la dichiarazione (extern int const n;) in un file di intestazione, e comprendono che in sia a.cpp e b.cpp. Il collegamento è determinato dalla prima dichiarazione del visualizzata dal compilatore, quindi la definizione successiva in a.cpp avrà il collegamento corretto (esterno).

In alternativa, è possibile forzare il collegamento nella definizione:

extern int const n = 8; 

Nonostante la extern, questo è ancora una definizione; qualsiasi cosa con un inizializzatore al di fuori di una definizione di classe è una definizione.

2

Dichiarare che extern in a.cpp e basta usare senza extern in b.cpp:

ah

extern const int n ; 

a.cpp

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

b.cpp:

#include "a.h" 
... 


int main() 
{   
    int m = n; 
} 
+0

Hmm, usato per fare questo con un file di intestazione. Includere l'intestazione con l'extern è il modo più semplice. – Gjordis

+1

In realtà, dovresti rimuovere * 'const int n;' da b.cpp. L'intestazione inclusa è ciò che è necessario. – Roddy

+0

@Roddy corretto, modificato di conseguenza. – Gjordis

5

const e constexpr variabili C++ hanno collegamento interno (e quindi non sono accessibili in altre unità di compilazione) se non sono dichiarati extern (nella definizione o in una dichiarazione precedente).

In C, non è il caso (beh C non ha constexpr), quindi il codice è valido e più è possibile inserire extern in una definizione.

Quindi, se si vuole scrivere il codice che è sia C e C++ (e le due dichiarazioni dovrebbe probabilmente provengono dalla stessa intestazione come James ha sottolineato):

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

// b.cpp 
extern const int n; 

int main() 
{ 

    int m = n; 
} 

se non lo fai

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

è anche possibile

+0

@Roddy, corretto. Non esitare a sistemare cose del genere tu stesso invece di commentare. – AProgrammer

1

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

Da queste regole è sufficiente aggiungere la parola chiave extern alla definizione. ce l'hai già nella dichiarazione.

1

Se le altre risposte qui non fanno il trucco, può essere il caso di avere le definizioni dei diversi spazi dei nomi in ... Se la compilazione passa, e si ottiene un errore undefined symbol linker:

  • controlla lo spazio dei nomi del simbolo non definito; questo è lo spazio dei nomi effettivo per la dichiarazione extern const int n.
  • assicurati che questo sia lo spazio dei nomi effettivo in cui si effettua la definizione const int n = 8.