2013-08-10 19 views
8

Ho un programma con alcune stringhe globali definiti nella parte superiore del file in questo modo:C: Assegnazione di "static const char * const" a "static const char *"

static const char * const STRING_A = "STRING A"; 
static const char * const STRING_B = "STRING B"; 

Poi nel programma principale loop, chiamo ripetutamente una funzione. Questa funzione contiene un puntatore che punta alle stringhe sopra, a seconda dell'input dell'utente. Per impostazione predefinita, lo voglio essere impostato su STRING_A, quindi quello che essenzialmente ho è questa:

// Called repeatedly from a loop. 
void input_function() 
{ 
    static const char *current = STRING_A; 

    // Do stuff and reassign different strings to "current" 
    ... 
} 

Il problema che ho è che durante la compilazione ottengo "Errore: elemento inizializzatore non è costante". Questo sta usando GCC 4.7.2. Ciò che mi confonde di più è che l'errore scompare se si elimina la parola chiave "statica" nella funzione di input. Questa non è una soluzione, tuttavia, poiché la parola chiave static è necessaria affinché la funzione tenga traccia della stringa corrente tra le chiamate.

Ovviamente potrei risolvere il problema in molti modi, semplicemente semplicemente liberandomi da alcune delle qualifiche di const. Ma voglio capire perché questo non funziona.

La mia attuale comprensione è che le variabili di stringa globali non possono essere modificate per puntare a stringhe diverse, e nessuno dei due può modificare i loro singoli caratteri. La parola chiave static li mantiene locali al file sorgente.

Per la variabile current nella mia funzione mia comprensione è che la parola chiave static permette di mantenere il suo valore su più chiamate alla funzione, e che il qualificatore const in questo caso significa che la stringa puntata da current può cambiare - ma non i caratteri della stringa a cui punta.

Non vedo alcun conflitto in queste istruzioni, quindi non capisco perché il compilatore restituisca un errore, in particolare perché non ha un problema se l'identificatore "statico" dello current viene rimosso.

Grazie se qualcuno può spiegare qual è il problema.

risposta

7

6.7.8/4 [C99]:

All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.

STRING_A è né, quindi l'errore.

Uno a modo per aggirare questo sarebbe lungo le seguenti linee:

void input_function() 
{ 
    static const char *current = NULL; 
    if (current == NULL) { 
     current = STRING_A; 
    } 

    ... 
} 
+0

sto ancora confezionamento mia testa intorno ad esso, ma grazie per la risposta rapida. –

3

È perché STRING_A non è una costante della fase di compilazione. Le tue interpretazioni sono giuste, tuttavia non è possibile inizializzare una costante per essere un valore non costante (ad esempio STRING_A).

Come fa il compilatore a sapere quali sono i punti STRING_A mentre è in fase di compilazione? Non - STRING_A punterà a indirizzi diversi nella sezione di sola lettura della memoria su ogni esecuzione del programma, a seconda di dove la stringa letterale è in memoria.

Si avrebbe bisogno di effettuare le seguenti operazioni per aggirare questo vincolo, mentre lo stesso effetto di pertinenza:

// Defines current to be a null pointer. 
static const char *current = NULL; 

// Determine if current is a null pointer. 
if (current == NULL) current = STRING_A; 
+0

Grazie per la rapida risposta, ho dovuto darlo a NPE anche perché era in qualche modo ancora più veloce. Grazie ancora. –