2013-02-20 19 views
10

voglio fornire una costante stringa in un'API in questo modo:extern const char * const SOME_CONSTANT mi dà errori del linker

extern const char* const SOME_CONSTANT; 

Ma se io definisco nel mio file sorgente libreria statica come

const char* const SOME_CONSTANT = "test"; 

ricevo errori del linker quando si collegano contro quella biblioteca e l'utilizzo di SOME_CONSTANT:

errore 1 errore LNK2001: simbolo esterno " const char * const SOME_CONSTANT"(? SOME_CONSTANT @@ 3QBDB)

Rimozione del puntatore const-ness (seconda parola chiave const) sia dalla dichiarazione e la definizione rende il lavoro extern const char* const. Come posso esportarlo con il puntatore con il puntatore?

+0

beh, sembra che dovrebbe essere okay http://stackoverflow.com/questions/2190919/mixing-extern-and-const –

+0

Visto come lo hai codificato in C++, non dovrebbe una "costante di stringa" essere effettivamente 'const std :: string' in primo luogo? – Angew

+0

Inoltre, la dichiarazione 'extern' è visibile nel file sorgente che definisce la costante? – Angew

risposta

11

Il problema potrebbe essere che la dichiarazione extern non è visibile nel file di origine che definisce la costante. Provare a ripetere la dichiarazione sopra la definizione, in questo modo:

extern const char* const SOME_CONSTANT; //make sure name has external linkage 
const char* const SOME_CONSTANT = "test"; //define the constant 
+0

Questo funziona. Mi stavo chiedendo come il linker sa che non dovrebbe spogliare il mio simbolo ... e poi ho visto la tua risposta e facepalmed: D Ovviamente devo applicare il collegamento extern. – AndiDog

+3

@AndiDog Si noti che equivale a aggiungere "extern" alla definizione. Come suggerisce l'altra risposta, 'const' in C++ implica' static'. Quindi devi neutralizzarlo e dire esplicitamente "extern" anche nella tua definizione. –

+1

"' const' in C++ implica 'static' ... Questo sembra un arbitrario hack nelle specifiche C++. Micro ottimizzazione per i pigri !!! – FooF

9

molto probabilmente si è dimenticato di includere l'intestazione nel file di implementazione

in ogni caso, aggiungere la parola chiave extern alla definizione

senza extern dichiarazione ha il collegamento interno e quindi non è visibile al linker

+0

Questo sembra vero (testato con recente 'gcc' in Linux), +1 per te. Perché è così? Qual è il razionale qui? Per assicurarsi che la dichiarazione e la definizione del file di intestazione corrispondenza? Qualsiasi link alla spiegazione di questo comportamento imbarazzante? – FooF

+0

re le motivazioni, perché le costanti non-'extern 'hanno il collegamento interno in C++, penso che abbia a che fare con l'evitamento di collisioni di nomi inutili e conflitti di regole di definizione per il collegamento. C99 ha una caratteristica che è * come * ma non esattamente le stesse regole (non sono sicuro dei dettagli). essenzialmente significa che puoi dichiarare più liberamente * e definire * le costanti nei file di intestazione. Potresti considerare di spostare la definizione costante nel file di intestazione e quindi semplicemente omettere "extern". Potresti quindi aggiungere un 'static' per una buona misura, ma non è necessario: è di questo che si tratta. –

+0

Come accennato, c'è sempre la ben nota possibilità di definire 'stat const char * const SOME_CONSTANT =" test ";' nel file di intestazione. Oppure potremmo inserire la definizione nello spazio dei nomi anonimo nell'intestazione ... Questo mi sembra ancora uno stupido trucco che aggiunge semplicemente complessità inutile alla definizione del linguaggio !!! Forse è stato considerato più leggibile per i file di intestazione che non devono essere ingombri di abbracci 'static' o namespace anonimi. – FooF