2
votes

Où les Enum sont-ils stockés?

Les structures ont une existence logique et prennent vie lorsqu'une variable de structure est définie. Je veux savoir comment les enum sont stockés s'ils prennent vie immédiatement après leur déclaration. Est-ce juste une existence logique?

#include<stdio.h>
enum tag{
a,
b};
struct tag1 {
int temp;
}var;
int main(){
int a=9;
printf("%d %d\n",a,b);
printf("%d\n",var.temp);
}

J'ai entendu dire que les énumérations ne sont pas stockées en mémoire, donc ma question est de savoir d'où b tire sa valeur.


5 commentaires

Un petit exemple de code à discuter aidera vraiment à clarifier ce que vous voulez dire. J'ai peur de ne pas te suivre.


Non. modifiez votre question avec elle s'il vous plaît.


Le b dans la fonction est le nom de la constante d'énumération b (valeur 1 ). La variable entière a dans la fonction cache ('shadows') la constante d'énumération a ; vous ne pouvez pas faire référence à la constante d'énumération a dans main () après avoir déclaré la variable locale a . La variable est affectée 9 , en savoir plus sur les portées des variables - c'est crucial pour comprendre ce code. Le type de structure existe et vous avez déclaré une variable var à la portée du fichier (global); il est initialisé avec des zéros. Par conséquent, votre code imprime 9 1 0 sur deux lignes.


"Est-ce juste une existence logique?" Il existe de la même manière qu'un 7 ou un 'x' existe.


Où est la constante d'énumération b présente. Et quand les affectations des recenseurs sont-elles effectuées?


4 Réponses :


3
votes

b est remplacé par sa valeur (1 dans votre cas) lors de la compilation. Elle sera donc traitée de la même manière qu'une constante et il n'est pas possible d'obtenir son adresse comme une variable.


0 commentaires

2
votes

Je vous conseille de jeter un œil à la définition de l'objet N1570 3.15 objet :

région de stockage des données dans l'environnement d'exécution, le contenu de qui peut représenter des valeurs

et constante 6.4.4 (p2):

Chaque constante a un type, déterminé par sa forme et sa valeur, comme détaillé plus tard

Il n'est donc pas spécifié si une constante nécessite un stockage dans l'environnement d'exécution et ne peut donc exister qu'au moment de la compilation.

Puisque constante d'énumération est un constant il n'est pas spécifié pour eux non plus. Les chaînes littérales, par exemple, sont placées dans la section .rodata et peuvent donc être lues, mais en les modifiant très probablement, elles seront SEGV (bien que ce soit UB).

Pour être plus précis, essayons de regarder la section .rodata de votre exemple. Voici objdump -dj .rodata bin_name :

Disassembly of section .rodata:

0000000000000720 <_IO_stdin_used>:
 720:   01 00 02 00 25 64 20 25 64 0a 00 25 64 0a 00        ....%d %d..%d..

Comme vous pouvez le voir, il contient le seul littéral de chaîne.


2 commentaires

La chaîne littérale commence à 25 . Le 01 00 pourrait être les constantes d'énumération pour tout ce que nous savons (mais probablement autre chose).


@Lundin Quoi qu'il en soit, j'ai tendance à supposer que les compilateurs peuvent optimiser cela, donc je ne me fierais pas à cela.



2
votes

Les constantes d'énumération sont des valeurs. Ils se comportent comme les autres valeurs entières, telles que 3 ou -87. Le compilateur les construit dans le code comme il le souhaite: ils peuvent être encodés comme des opérandes immédiats dans des instructions, chargés à partir de la mémoire que le compilateur utilise pour contenir des constantes, ou intégrés dans des expressions qui sont partiellement ou complètement évaluées au moment de la compilation.

Les valeurs n’ont pas de durée de vie dans le modèle de calcul abstrait de C. Seuls les objets ont des durées de vie et les valeurs ne sont pas des objets. (Les objets sont des parties réservées de la mémoire qui sont utilisées pour représenter des valeurs.)


0 commentaires

3
votes

Une énumération standard est généralement implémentée en tant que int32, le compilateur gérera votre énumération comme synonyme de int32. Une fois qu'une liste de valeurs est créée pour une énumération, ces valeurs sont stockées sous forme de littéraux par rapport à leur nom d'affichage (nom d'accès donné à l'heure de la déclaration d'énumération). Par conséquent, votre enum est à la fin un int32 qui est codé en dur dans la mémoire de la même manière qu'une constante.


1 commentaires

Les constantes d'énumération sont toujours implémentées comme int - ceci est requis par la norme. Ce qui peut à son tour être 32 bits (commun) ou 16 bits (commun) ou quelque chose d'exotique (uniquement possible en théorie). Les variables d'énumération peuvent cependant être d'autres types d'entiers que int - adaptables à la taille requise pour contenir toutes les constantes répertoriées.