Memoria allocata in fase di compilazione significa che il compilatore si risolve in fase di compilazione in cui determinate cose verranno allocate all'interno della mappa della memoria di processo.
Ad esempio, considera un array globale:
int array[100];
Il compilatore conosce in fase di compilazione la dimensione dell'array e la dimensione di un int
, quindi conosce l'intera dimensione dell'array in fase di compilazione. Anche una variabile globale ha una durata di archiviazione statica per impostazione predefinita: è allocata nell'area di memoria statica dello spazio di memoria del processo (sezione .data / .bss). Date queste informazioni, il compilatore decide durante la compilazione in quale indirizzo dell'area di memoria statica sarà l'array .
Naturalmente gli indirizzi di memoria sono indirizzi virtuali. Il programma presuppone che disponga di un proprio spazio di memoria (ad esempio, da 0x00000000 a 0xFFFFFFFF). Ecco perché il compilatore potrebbe fare ipotesi come "Okay, l'array sarà all'indirizzo 0x00A33211". In fase di esecuzione, gli indirizzi vengono tradotti in indirizzi reali / hardware da MMU e sistema operativo.
Le cose di archiviazione statica inizializzata dal valore sono leggermente diverse. Per esempio:
int array[] = { 1 , 2 , 3 , 4 };
Nel nostro primo esempio, il compilatore ha deciso solo dove verrà allocato l'array, memorizzando tali informazioni nell'eseguibile.
Nel caso di cose inizializzate dal valore, il compilatore inserisce anche il valore iniziale dell'array nell'eseguibile e aggiunge il codice che dice al caricatore del programma che dopo l'allocazione dell'array all'avvio del programma, l'array deve essere riempito con questi valori.
Ecco due esempi dell'assembly generato dal compilatore (GCC4.8.1 con target x86):
Codice C ++:
int a[4];
int b[] = { 1 , 2 , 3 , 4 };
int main()
{}
Gruppo di uscita:
a:
.zero 16
b:
.long 1
.long 2
.long 3
.long 4
main:
pushq %rbp
movq %rsp, %rbp
movl $0, %eax
popq %rbp
ret
Come puoi vedere, i valori vengono iniettati direttamente nell'assieme. Nell'array a
, il compilatore genera un'inizializzazione zero di 16 byte, poiché lo standard afferma che le cose memorizzate statiche dovrebbero essere inizializzate a zero per impostazione predefinita:
8.5.9 (Inizializzatori) [Nota]:
ogni oggetto con durata di memorizzazione statica viene inizializzato a zero all'avvio del programma prima che avvenga qualsiasi altra inizializzazione. In alcuni casi, l'inizializzazione aggiuntiva viene eseguita in seguito.
Suggerisco sempre alle persone di smontare il loro codice per vedere cosa fa veramente il compilatore con il codice C ++. Ciò si applica dalle classi di archiviazione / durata (come questa domanda) alle ottimizzazioni avanzate del compilatore. Potresti incaricare il tuo compilatore di generare l'assembly, ma ci sono strumenti meravigliosi per farlo su Internet in modo amichevole. Il mio preferito è GCC Explorer .