227 votes

Où sont stockées les variables statiques en C et C++ ?

Dans quel segment (.BSS, .DATA, autre) d'un fichier exécutable les variables statiques sont-elles stockées afin qu'elles n'aient pas de collision de noms ? Par exemple :

foo.c:                         bar.c:
static int foo = 1;            static int foo = 10;
void fooTest() {               void barTest() {
  static int bar = 2;            static int bar = 20;
  foo++;                         foo++;
  bar++;                         bar++;
  printf("%d,%d", foo, bar);     printf("%d, %d", foo, bar);
}                              }

Si je compile les deux fichiers et que je les lie à un main qui appelle fooTest() et barTest à plusieurs reprises, les instructions printf s'incrémentent indépendamment. C'est logique puisque les variables foo et bar sont locales à l'unité de traduction.

Mais où le stockage est-il alloué ?

Pour être clair, l'hypothèse est que vous avez une chaîne d'outils qui produirait un fichier au format ELF. Ainsi, je croire qu'il y a a il doit y avoir un espace réservé dans le fichier exécutable pour ces variables statiques.
Pour les besoins de la discussion, supposons que nous utilisons la chaîne d'outils GCC.

3 votes

La plupart des gens vous disent qu'ils doivent être stockés dans la section .DATA au lieu de répondre à votre question : où se trouve exactement la section .DATA et comment la trouver. Je vois que vous avez déjà marqué une réponse, donc vous savez déjà comment la trouver ?

0 votes

Pourquoi l'initialisé et le non-initialisé sont placés dans des sections différentes : linuxjournal.com/article/1059

3 votes

Le stockage alloué à vos variables globales/statiques au moment de l'exécution n'a rien à voir avec la résolution de leur nom, qui a lieu au moment de la construction/liaison. Une fois que l'exécutable a été construit, il n'y a plus de noms.

160voto

Don Neufeld Points 12803

L'endroit où vont vos statiques dépend du fait qu'elles soient zéro initialisé . zéro initialisé les données statiques vont dans .BSS (Bloc démarré par un symbole) , non-zéro-initialisé les données sont introduites .DATA

58 votes

Par "non-0 initialisé", vous voulez probablement dire "initialisé, mais avec autre chose que 0". Parce que les données statiques "non initialisées" n'existent pas en C/C++. Tout ce qui est statique est initialisé à zéro par défaut.

25 votes

@Don Neufeld : votre réponse ne répond pas du tout à la question. Je ne comprends pas pourquoi elle est acceptée. Parce que les deux 'foo' et 'bar' ne sont pas initialisés à 0. La question est de savoir où placer deux variables statiques/globales avec le même nom dans .bss ou .data.

0 votes

J'ai utilisé des implémentations où les données statiques qui étaient explicitement initialisées à zéro allaient dans .data et les données statiques sans initialisateur sont placées dans .bss .

141voto

karn Points 2442

Lorsqu'un programme est chargé en mémoire, il est organisé en différents segments. L'un des segments est Segment DATA . Le segment des données est encore subdivisé en deux parties :

Segment de données initialisé : Toutes les données globales, statiques et constantes sont stockées ici.
Segment de données non initialisé (BSS) : Toutes les données non initialisées sont stockées dans ce segment.

Voici un schéma pour expliquer ce concept :

enter image description here

Voici un très bon lien expliquant ces concepts :

http://www.inf.udec.cl/~leo/teoX.pdf

0 votes

La réponse ci-dessus dit que 0 initialisé va dans BSS. Est-ce que 0 initialisé signifie non initialisé ou 0 en soi ? Si cela signifie 0 en soi, je pense que vous devriez l'inclure dans votre réponse.

0 votes

Les données constantes ne sont pas stockées dans le segment .data mais dans le segment .const de la section texte.

2 votes

Au lieu de cela (" Segment de données initialisé : Toutes les données globales, statiques et constantes sont stockées ici. Segment de données non initialisé (BSS) : Toutes les données non initialisées sont stockées dans ce segment."), je pense que cela devrait dire ceci : ("" Segment de données initialisé : Toutes les variables globales et statiques qui ont été initialisées à une valeur non nulle, et toutes les données constantes, sont stockées ici. Segment de données non initialisé (BSS) : Toutes les variables globales et statiques qui n'ont PAS été initialisées, ou qui ont été initialisées à zéro, sont stockées dans ce segment.").

39voto

yogeesh Points 449

En fait, une variable est un tuple (stockage, portée, type, adresse, valeur) :

storage     :   where is it stored, for example data, stack, heap...
scope       :   who can see us, for example global, local...
type        :   what is our type, for example int, int*...
address     :   where are we located
value       :   what is our value

La portée locale peut signifier locale à l'unité de translation (fichier source), à la fonction ou au bloc selon l'endroit où elle est définie. Pour rendre une variable visible par plus d'une fonction, elle doit absolument se trouver dans la zone DATA ou BSS (selon qu'elle est initialisée explicitement ou non, respectivement). Sa portée est alors adaptée soit à toutes les fonctions, soit aux fonctions du fichier source.

27voto

Seb Rose Points 2145

L'emplacement de stockage des données dépendra de l'implémentation.

Cependant, la signification de statique est "lien interne". Ainsi, le symbole est interne à l'unité de compilation (foo.c, bar.c) et ne peut être référencé en dehors de cette unité de compilation. Il ne peut donc pas y avoir de collision de noms.

0 votes

Non. static keyworld a des significations surchargées : dans ce cas static est un modificateur de stockage, pas un modificateur de liaison.

4 votes

Ugasoft : les statiques à l'extérieur de la fonction sont des modificateurs de liaison, à l'intérieur ce sont des modificateurs de stockage où il ne peut y avoir de collision au départ.

13voto

paxdiablo Points 341644

Je ne crois pas qu'il y aura une collision. L'utilisation de static au niveau du fichier (en dehors des fonctions) marque la variable comme locale à l'unité de compilation actuelle (fichier). Elle n'est jamais visible en dehors du fichier actuel et n'a donc jamais besoin d'avoir un nom qui puisse être utilisé en externe.

Utilisation d'un système statique à l'intérieur de une fonction est différente - la variable n'est visible que pour la fonction (qu'elle soit statique ou non), c'est juste sa valeur qui est préservée à travers les appels à cette fonction.

En effet, la statique fait deux choses différentes selon l'endroit où elle se trouve. Sur les deux Cependant, dans les cas où la visibilité des variables est limitée, vous pouvez facilement éviter les conflits d'espace de noms lors de l'établissement de liens.

Cela dit, je pense qu'elle serait stockée dans le fichier DATA qui a tendance à avoir des variables qui sont initialisées à des valeurs autres que zéro. Il s'agit, bien entendu, d'un détail d'implémentation, et non d'un élément imposé par la norme - elle ne s'intéresse qu'à comportement, pas comment les choses sont faites sous la couverture.

2 votes

@paxdiablo : vous avez mentionné deux types de variables statiques. Lequel d'entre eux cet article ( fr.wikipedia.org/wiki/Data_segment ) font référence ? Le segment de données contient également les variables globales (qui sont de nature exactement opposée aux variables statiques). So, how does a segment of memory (Data Segment) store variables that can be accessed from everywhere (global variables) and also those which have limited scope (file scope or function scope in case of static variables)?

0 votes

@eSKay, cela a à voir avec la visibilité. Il peut y avoir des choses stockées dans un segment qui sont locales à une unité de compilation, d'autres qui sont entièrement accessibles. Un exemple : imaginez que chaque unité de compilation contribue à un bloc dans le segment DATA. Elle sait où tout est dans ce bloc. Il publie également les adresses des éléments du bloc auxquels il souhaite que les autres unités de calcul aient accès. L'éditeur de liens peut résoudre ces adresses au moment de la liaison.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X