2016-06-02 50 views
5

Questo problema è riproducibile nel g ++ prima di -std=c++14. Viene generato un errore di collegamento a causa di evidenziato const mostrato nei seguenti codici. Scompare se RHS const viene rimosso.Errore di collegamento dovuto alla costanza dell'array di puntatori in C++ 03/C++ 11

/* main.cpp */ 
const char* const arr[2] = {"Hello", "World"}; 
//   ^^^^^ 
int main() {} 

e

/* foo.cpp */ 
extern const char* const arr[2]; 
//     ^^^^^ 
const char* foo() { return arr[0]; } 

Durante la compilazione: g++ [-std=c++11] main.cpp foo.cpp, dà errore seguente collegamento:

In function `foo()': undefined reference to `arr' 

Si tratta di un bug del compilatore o di una limitazione di linguaggio/funzione?

+3

'variabili const' a portata namespace [sono implicitamente' static'] (http://stackoverflow.com/questions/33402177/const-global-variable-in-namespace), a meno che non si aggiunge 'extern'. Non sono sicuro del perché il comportamento cambi con '-std = C++ 14'. – Quentin

+0

Non dovrebbe 'extern const char * const arr [2];' essere in un file di intestazione che include sia 'main.cpp' che' foo.cpp'? – NathanOliver

+0

@Quentin Non sono sicuro del motivo per cui OP dice pre C++ 14, g ++ 5.1.0 produce errore in qualsiasi modalità (C++ 14 C++ 17), il tuo commento dovrebbe essere la risposta – Slava

risposta

3

Come notato da Quentin, il progetto di n4296 è esplicito al riguardo nel capitolo 3.5 del programma e il collegamento [basic.link] §3 (sottolineare il mio)

A name having namespace scope (3.3.6) has internal linkage if it is the name of
(3.1) — a variable, function or function template that is explicitly declared static; or,
(3.2) — a variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage;

Quando si dichiara arr essere const, è dato implicitamente collegamento interno. La correzione è banale:

/* main.cpp */ 
extern const char* const arr[2] = {"Hello", "World"}; 

Ma best practice raccomanda di avere extern const char* const arr[2]; in un'intestazione incluso in tutti i file utilizzando arr al fine di condividere correttamente la dichiarazione e quindi aggiungere in uno di quei file const char* const arr[2] = {"Hello", "World"};, in modo efficace ottenendo:

/* main.cpp */ 
extern const char* const arr[2]; // directly or more likely through an include... 
... 
const char* const arr[2] = {"Hello", "World"};