Je me demande où sont stockées les variables constantes. Est-ce dans la même zone mémoire que les variables globales? Ou est-ce sur la pile?
La façon dont ils sont stockés est un détail d'implémentation (dépend du compilateur).
Par exemple, dans le compilateur GCC, sur la plupart des machines, les variables en lecture seule, les constantes et les tables de saut sont placées dans la section de texte.
Selon la segmentation des données suivie par un processeur particulier, nous avons cinq segments:
Notez que la différence entre les segments de données et BSS réside dans le fait que l’ancien stocke les variables globales et statiques initialisées et les dernières stocke les variables non initialisées.
Maintenant, pourquoi est-ce que je parle de la segmentation des données alors que je dois simplement dire où sont stockées les variables constantes ... il y a une raison à cela ...
Chaque segment a une région protégée en écriture où toutes les constantes sont stockées.
Par exemple:
Pour résumer, "const" est juste un QUALIFICATEUR de données, ce qui signifie que le compilateur doit d’abord décider quel segment la variable doit être stocké, puis si la variable est une constante, elle est qualifiée pour être stockée dans la région protégée en écriture de ce segment particulier.
Considérons le code:
const int i = 0;
static const int k = 99;
int function(void)
{
const int j = 37;
totherfunc(&j);
totherfunc(&i);
//totherfunc(&k);
return(j+3);
}
De manière générale, i
peut être stocké dans le segment de texte (c'est une variable en lecture seule avec une valeur fixe). Si ce n'est pas dans le segment de texte, il sera stocké à côté des variables globales. Étant donné qu'il est initialisé à zéro, il peut s'agir de la section "bss" (où les variables remises à zéro sont généralement allouées) ou de la section "données" (où les variables initialisées sont généralement allouées).
Si le compilateur est convaincu que la variable k
est inutilisée (comme il se peut qu'elle soit locale à un seul fichier), il est possible qu'elle n'apparaisse pas du tout dans le code de l'objet. Si l'appel à totherfunc()
qui fait référence à k
n'a pas été commenté, k
devrait alors se voir attribuer une adresse quelque part - elle se trouverait probablement dans le même segment que i
.
La constante (s'il s'agit d'une constante, s'agit-il encore d'une variable?) j
apparaîtra très probablement sur la pile d'une implémentation en C conventionnelle. (Si vous posez la question dans le groupe de discussion comp.std.c, quelqu'un dira que la norme ne dit pas que des variables automatiques apparaissent sur la pile; heureusement, SO n'est pas comp.std.c!)
Notez que j'ai forcé les variables à apparaître car je les ai passées par référence, probablement à une fonction qui attend un pointeur sur un entier constant. Si les adresses n'ont jamais été prises, alors j
et k
pourraient être optimisés en dehors du code. Pour supprimer i
, le compilateur doit connaître tout le code source du programme entier - il est accessible dans d'autres unités de traduction (fichiers source) et ne peut donc pas être supprimé aussi facilement. Doublement pas si le programme s'adonne au chargement dynamique de bibliothèques partagées - une de ces bibliothèques pourrait s'appuyer sur cette variable globale.
(Stylistiquement - les variables i
et j
devraient avoir des noms plus longs et plus significatifs; ce n'est qu'un exemple!)
Dépend de votre compilateur, des capacités de votre système, de votre configuration lors de la compilation.
gcc
met les constantes en lecture seule dans la section .text
, sauf indication contraire.
hors cours, parce que
1) Le segment bss stocke des variables non inilises. Il est évident qu’un autre type est présent.
(I) large static and global and non constants and non initilaized variables it stored .BSS section.
(II) second thing small static and global variables and non constants and non initilaized variables stored in .SBSS section this included in .BSS segment.
2) le segment de données est une variable initiée, il en a 3 types,
(I) large static and global and initlaized and non constants variables its stord in .DATA section.
(II) small static and global and non constant and initilaized variables its stord in .SDATA1 sectiion.
(III) small static and global and constant and initilaized OR non initilaized variables its stord in .SDATA2 sectiion.
je mentionne ci-dessus petits et grands moyens dépendant de complier par exemple petits moyens <à 8 octets et grands moyens> à 8 octets et valeurs égales.
mais mon doute est la constante locale sont où il va caresser ??????
Généralement, elles sont stockées dans une section de données en lecture seule (alors que la section de variables globales a des autorisations d'écriture). Ainsi, essayer de modifier une constante en prenant son adresse risque d’entraîner une violation d’accès appelée segfault.
Mais cela dépend vraiment de votre matériel, de votre système d’exploitation et de votre compilateur.
Il s’agit généralement d’une hypothèse éclairée, mais je dirais que les constantes sont généralement stockées dans les instructions de processeur de votre programme compilé, en tant que données immédiates. Donc, en d'autres termes, la plupart des instructions incluent un espace pour que l'adresse puisse extraire des données, mais si c'est une constante, l'espace peut contenir la valeur elle-même.
Tout comme un ajout, comme vous savez que pendant le processus de liaison, la disposition de la mémoire de l'exécutable final est décidée. sous la section .bss.
Il doit être stocké dans un segment de texte car il s'agit de variables en lecture seule. http://shirleyanengineer.blogspot.fr 2017/05/memory-layout-of-process.html
Global et constant sont deux mots-clés complètement séparés. Vous pouvez avoir l'un ou l'autre, aucun ou les deux.
Le lieu où votre variable est stockée en mémoire dépend de la configuration. Lisez un peu sur le tas et la pile , cela vous donnera quelques connaissances pour poser plus de questions (et si je peux, mieux et plus spécifique).
Certaines constantes ne sont même pas stockées.
Considérez le code suivant: int x = foo(); x *= 2;
. Il est fort probable que le compilateur transforme la multiplication en x = x+x;
, ce qui réduit le besoin de charger le nombre 2 à partir de la mémoire.
Il ne peut pas être stocké du tout.
Considérons un code comme celui-ci:
#import<math.h>//import PI
double toRadian(int degree){
return degree*PI*2/360.0;
}
Cela permet au programmeur de se faire une idée de ce qui se passe, mais le compilateur peut en optimiser certaines, comme le font la plupart des compilateurs, en évaluant des expressions constantes au moment de la compilation, ce qui signifie que la valeur PI peut ne pas figurer dans le programme résultant du tout.