La mémoire allouée au moment de la compilation signifie que le compilateur résout au moment de la compilation où certaines choses seront allouées à l'intérieur de la carte mémoire du processus.
Par exemple, considérons un tableau global:
int array[100];
Le compilateur connaît au moment de la compilation la taille du tableau et la taille de an int
, donc il connaît la taille entière du tableau au moment de la compilation. De plus, une variable globale a une durée de stockage statique par défaut: elle est allouée dans la zone mémoire statique de l'espace mémoire du processus (section .data / .bss). Compte tenu de ces informations, le compilateur décide lors de la compilation à quelle adresse de cette zone de mémoire statique le tableau sera .
Bien sûr, les adresses mémoire sont des adresses virtuelles. Le programme suppose qu'il dispose de son propre espace mémoire entier (de 0x00000000 à 0xFFFFFFFF par exemple). C'est pourquoi le compilateur pourrait faire des hypothèses telles que "D'accord, le tableau sera à l'adresse 0x00A33211". Au moment de l'exécution, ces adresses sont traduites en adresses réelles / matérielles par la MMU et le système d'exploitation.
Les éléments de stockage statique à valeur initialisée sont un peu différents. Par exemple:
int array[] = { 1 , 2 , 3 , 4 };
Dans notre premier exemple, le compilateur a uniquement décidé où le tableau sera alloué, en stockant ces informations dans l'exécutable.
Dans le cas de choses initialisées par valeur, le compilateur injecte également la valeur initiale du tableau dans l'exécutable et ajoute du code qui indique au chargeur de programme qu'après l'allocation du tableau au démarrage du programme, le tableau doit être rempli avec ces valeurs.
Voici deux exemples d'assembly généré par le compilateur (GCC4.8.1 avec cible x86):
Code C ++:
int a[4];
int b[] = { 1 , 2 , 3 , 4 };
int main()
{}
Assemblage de sortie:
a:
.zero 16
b:
.long 1
.long 2
.long 3
.long 4
main:
pushq %rbp
movq %rsp, %rbp
movl $0, %eax
popq %rbp
ret
Comme vous pouvez le voir, les valeurs sont directement injectées dans l'assemblage. Dans le tableau a
, le compilateur génère une initialisation à zéro de 16 octets, car la norme dit que les éléments stockés statiques doivent être initialisés à zéro par défaut:
8.5.9 (Initialiseurs) [Note]:
Chaque objet de durée de stockage statique est initialisé à zéro au démarrage du programme avant toute autre initialisation. Dans certains cas, une initialisation supplémentaire est effectuée ultérieurement.
Je suggère toujours aux gens de désassembler leur code pour voir ce que le compilateur fait vraiment avec le code C ++. Cela s'applique des classes / durée de stockage (comme cette question) aux optimisations avancées du compilateur. Vous pouvez demander à votre compilateur de générer l'assembly, mais il existe de merveilleux outils pour le faire sur Internet de manière conviviale. Mon préféré est GCC Explorer .