2009-11-07 5 views
11

Ho un problema nell'inizializzazione di un array le cui dimensioni sono definite come extern const. Ho sempre seguito la regola che le variabili globali dovrebbero essere dichiarate extern nei file di intestazione e le loro definizioni corrispondenti dovrebbero essere in uno dei file di implementazione al fine di evitare errori di redeclaration variabili. Questo approccio ha funzionato bene fino a quando ho dovuto inizializzare un array con la cui dimensione è definita come extern const. Viene visualizzato un errore indicante un'espressione costante. Tuttavia, se provo ad assegnare un valore alla variabile const, il compilatore si lamenta correttamente che un valore non può essere assegnato a una variabile costante. Ciò dimostra che il compilatore vede la variabile come una costante. Perché allora viene segnalato un errore quando provo a dichiarare un array della stessa dimensione?Dichiarazione di un array la cui dimensione è dichiarata come externale

C'è un modo per evitarlo senza usare #define? Vorrei anche sapere il motivo di questo errore.

Package.h:

#ifndef PACKAGE_H 
#define PACKAGE_H 

extern const int SIZE; 

#endif 

Package.cpp:

#include "Package.h" 

const int SIZE = 10; 

Foo.cpp:

#include "Package.h" 

int main() 
{ 
    // SIZE = 5; // error - cannot assign value to a constant variable 
    // int Array[SIZE]; // error - constant expression expected 
    return 0; 
} 
+0

È possibile inserire il codice con quattro spazi per formattarlo. – Thomas

risposta

16

La costante è esterna, quindi è definita in un'altra unità di compilazione (file .o). Pertanto, il compilatore non può determinare la dimensione dell'array in fase di compilazione; non è noto fino al momento del collegamento quale sarà il valore della costante.

3

Beh, vede la variabile come const qualificato, non come un'espressione costante.

2

Credo che il problema qui sia che se dichiarate la vostra variabile come extern, è permesso che sia in un diverso modulo (.o file) o anche in una libreria dinamica (.dll/.so). Ciò ovviamente significa che il compilatore potrebbe non essere in grado di risolvere il contenuto della variabile in fase di compilazione, rifiutandosi quindi di utilizzare il valore in cui è richiesto un const.

La mia opinione è, che è perfettamente ok non usare extern qui e dichiararlo direttamente nel file di intestazione, in quanto è un valore int comunque che sarà inline quando usato ovunque nel codice. Di solito uso extern const solo quando lavoro con le stringhe, poiché voglio assicurarmi che solo una istanza della stringa venga generata in fase di runtime.

3

Poiché è solo uno int, rimuoverei il extern e renderlo una definizione piuttosto che una dichiarazione. La ragione per cui dico questo è che anche se questo approccio pone un'istanza separata del numero intero in ogni file sorgente che include l'intestazione, immagino che la maggior parte dei compilatori ottimizzerà il suo utilizzo. In effetti è impossibile per il compilatore ottimizzare il suo uso se non lo fai, in modo che non venga ottimizzato da semplici espressioni aritmetiche.

Dal momento che è dichiarato const, avrà un collegamento interno e quindi non si otterranno problemi con simboli con più simboli in questo modo.

+0

Grazie. Penso di capirlo adesso. Ma, perché questo approccio non funziona per i puntatori const. Se definisco const char * FILE_NAME = "Log.txt" nel file di intestazione e includo il file di intestazione in più file sorgente, ricevo comunque un errore di collegamento. Non ricevo un errore per l'istruzione const char FILE_NAME [] = "Log.txt " – psvaibhav

+0

@psvaibhav: Questo non funzionerà perché' const char * 'dichiara che il puntatore è un puntatore-a-const e _non_ un puntatore costante. Ciò di cui hai bisogno è un' const' extra dopo il '* 'per fare il puntatore stesso costante cioè 'const char * const' – Troubadour

Problemi correlati