2011-10-25 19 views
7

In che modo un compilatore, C o C++ (ad esempio gcc) onora la dichiarazione const?Come viene implementato "const"?

Ad esempio, nel seguente codice, come fa il compilatore registra che la variabile ci è const e non può essere modificato?

int 
get_foo() { 
    return 42; 
} 

void 
test() 
{ 
    int i = get_foo(); 
    i += 5; 

    const int ci = get_foo(); 
    // ci += 7; // compile error: assignment of read-only variable ?ci? 
} 
+5

Allo stesso modo tiene traccia di tutte le informazioni in fase di compilazione su var iables? –

+0

È fatto in fase di compilazione tramite il sistema di tipi. –

+1

Il tuo commento dovrebbe leggere "assegnazione alla variabile di sola lettura". A proposito, come pensi che il compilatore sappia che è un numero intero? – hplbsh

risposta

9

Molto simile a qualsiasi altro bit di informazioni sui simboli per le variabili (indirizzo, tipo ecc.). Di solito c'è una tabella dei simboli che memorizza le informazioni sugli identificatori dichiarati, e questa viene consultata ogni volta che incontra un altro riferimento all'identificatore.

(Una domanda più interessante è se questa conoscenza è presente solo durante la compilazione o durante il runtime.La maggior parte delle lingue scartare la tabella dei simboli dopo la compilazione, in modo da poter manipolare il codice compilato e forzare un nuovo valore anche se l'identificatore è stato dichiarato 'const'. Impedisce un sofisticato sistema di runtime (e la firma del codice) per impedirlo.)

+0

Per aggiungere a questo, un problema standard C++/C Compiler non fa molto se non altro per mantenere una variabile come questo "const" in fase di esecuzione, semplicemente sa di non generare alcun codice che possa modificare questo valore tramite la tabella dei simboli Kilian menzionato. Consequentemente, qualche altro compilatore potrebbe creare del codice e se quel codice è stato caricato nel processo, potrebbe sovrascrivere la memoria in quella posizione. Questo è male. – Dlongnecker

+1

I dati di Const possono essere inseriti in un diverso blocco di memoria e su alcuni sistemi il blocco di memoria verrà effettivamente contrassegnato come di sola lettura. Molto simile al codice stesso risiede in un segmento diverso (forse i dati const e il codice possono essere mescolati). Ovviamente questo vale solo per le coste statiche e niente creato in pila. –

1

Il compilatore sa che ci è const perché hai detto così con la linea

const int ci = get_foo(); 

Come si passa ci intorno ad altre funzioni o assegnare ad altre variabili, il compilatore conserva che const- ness impedendoti di fare qualsiasi cosa che potrebbe potenzialmente cambiare il suo valore.

Ad esempio, quanto segue produce un errore del compilatore.

int *ci2 = &ci; 
(*ci2)++; 

Perché il compilatore non consente di modificare il valore di ci.

+0

L'ultimo esempio dovrebbe produrre un errore del compilatore anche senza l'operazione di incremento. Non è possibile assegnare un valore pointer-to-const a una variabile pointer-to-non-const. – Novelocrat

3

Naturalmente è l'attuazione di ciascun compilatore, ma in poche parole, esso memorizza const e volatile qualificazioni della variabile (se presente) nella sua tabella dei simboli variabile insieme ad altre informazioni come il tipo di variabile e se non è un puntatore/riferimento.

+0

"Qualifiche CV"? Sicuramente le variabili non hanno curriculum vitae! – Gabe

+1

@Gabe: lo standard parla molto di loro (const/volatile) nella sezione 3.9.3 "Qualificazioni CV". –

1

Sono sicuro che altri possono elaborare di più, ma in breve, sì. Il compilatore tiene traccia di tutti gli specificatori di tipi in modo che sappia che ci è di tipo "const int" e non "int".

1

Come altri hanno già detto, const viene tracciato dal compilatore nello stesso modo in cui il compilatore tiene traccia del fatto che una variabile è uno int. In effetti, ho letto che almeno gcc considera const int un tipo distinto da int, quindi non è nemmeno tracciato come modificatore, è tracciato allo stesso modo di uno int.

Si noti che in realtà si può cambiare il valore di un const tramite puntatore di fusione, ma il risultato non è definito:

#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 
     const int c = 0; 
     printf("%d\n", c); 
     ++*(int*)&c; 
     printf("%d\n", c); 
} 

Sulla mia macchina utilizzando gcc, Questo stampa

0 
1 

Ma la compilazione con g ++ dà

0 
0 
Problemi correlati