Lorsque sont statiques et variables globales initialisées?
Dans C++
je sais static
et global
les objets sont construits avant le main
fonction. Mais comme vous le savez, dans C
, il n'y a pas ce genre initialization procedure
avant main
.
Par exemple, dans mon code:
int global_int1 = 5;
int global_int2;
static int static_int1 = 4;
static int static_int2;
- Quand ces quatre variables initialisé?
- Où les valeurs d'initialisation comme
5
et4
sont stockées lors de la compilation? Comment les gérer lors de l'initialisation?
EDIT:
La Clarification de la 2ème question.
- Dans mon code j'utilise
5
à initialiserglobal_int1
, donc comment le compilateur attribuer5
àglobal_int
? Par exemple, peut-être que le compilateur premier magasin de la5
de la valeur à quelque part (c'est à dire un tableau), et d'obtenir cette valeur lors de l'initialisation commence. - À "la Façon de les gérer lors de l'initialisation?", il est vraiment vague et j'ai moi-même ne pas savoir comment interpréter encore. Parfois, il n'est pas facile à expliquer une question. L'ignorer, puisque je n'ai pas maîtrisé la question encore.
- Tous les quatre de vos variables statiques de classe de stockage.
- Comment
static storage class
se rapportent à ma question? - La classe de stockage détermine le comportement d'initialisation.
- Similaire discussion intéressante ici stackoverflow.com/questions/898432/...
- Je sais qu'il existe un procédé d'initialisation avant de
maìn
en C, car la C les spécifications dit qu'il y a (voir C99 5.1.2/1). - Pourriez-vous préciser ce que vous entendez par "la Façon de les gérer lors de l'initialisation"? En tant que programmeur, vous n'avez rien à faire au-delà de la définition d'entre eux, et en fournissant une initialiser si nécessaire.
- Le C99 5.1.2/1, en effet, dit Tous les objets statiques durée de stockage doit être initialisé (fixés à leurs valeurs initiales) avant le démarrage du programme. Les modalités et le calendrier de ces initialisation sont autrement non spécifié. Mais à la différence de C++ qui définit une fonction nommée
_start
sousgcc C
- Comment statique de la classe de stockage de déterminer le processus d'initialisation?
- C permet uniquement de ce que le C++ appelle initialisation statique. C++ ne permettent dynamiques, l'initialisation se produire après l'entrée
main
, officiellement, mais tous les compilateurs ne initialiser des variables statiques, avant demain
, et il ya une assez grande quantité de code qui en dépend.
Vous devez vous connecter pour publier un commentaire.
Par l'électricité statique et des objets globaux, je présume que tu veux dire avec des objets
statique de la durée de vie définie à l'espace de noms de champ. Lorsque ces objets
sont définis avec une portée locale, les règles sont légèrement différentes.
Formellement, C++ initialise des variables en trois phases:
1. Zéro initialisation
2. Initialisation statique
3. Dynamique de l'initialisation
La langue également fait la distinction entre les variables qui nécessitent
dynamique de l'initialisation, et celles qui nécessitent statique
initialisation: tous les objets statiques (objets statiques
durée de vie) sont d'abord initialisé à zéro, alors les objets statiques
initialisation sont initialisés, et puis la dynamique de l'initialisation
se produit.
Comme une simple première approximation, dynamique de l'initialisation de moyens
que certains de code doit être exécuté; en général, statique
l'initialisation n'a pas. Donc:
Un autre approximization serait que initialisation statique est
ce que le C prend en charge (pour les variables statiques de la vie), dynamique
tout le reste.
Comment le compilateur ne cela dépend, bien sûr, sur le
l'initialisation, mais sur le disque en fonction des systèmes, où l'exécutable
est chargé en mémoire à partir du disque, les valeurs statiques
l'initialisation de la partie de l'image sur le disque, et chargé
directement par le système à partir du disque. Sur un Unix classique
système, variables globales serait divisé en trois "segments":
les variables avec "const" types sera également placé ici.
initialisation (C++). L'exécutable contient pas d'image pour cette
segment, et le système définit simplement tout à " 0 " avant
départ de votre code.
Je soupçonne que beaucoup de systèmes modernes utilisent encore quelque chose
similaires.
EDIT:
Une remarque additionnelle: ci-dessus se réfère à C++03. Pour les
programmes C++11 n'a probablement pas changer quoi que ce soit, mais il ne
ajouter
constexpr
(ce qui signifie que certaines fonctions définies par l'utilisateurpeut-être encore initialisation statique) et le fil de variables locales,
qui ouvre une toute nouvelle boîte de pandore.
int i = f();
, vous pouvez voiri
comme0
dans certains constructeurs d'objets statiques, et que la valeur de retour def()
dans d'autres.Préface: Le mot "statique" a un grand nombre de significations différentes en C++. Ne pas se confondre.
Tous vos objets ont statique de la durée de stockage. C'est parce qu'ils ne sont ni automatiques ni dynamique. (Ni locale de thread, si le thread est un peu comme de l'électricité statique.)
En C++, les objets Statiques sont initialisés en deux phases: initialisation statique et dynamique de l'initialisation.
Dynamique d'initialisation nécessite code à exécuter, de sorte que ce qui se passe pour les objets qui commencent par un appel de constructeur, ou lorsque l'initialiseur, est une expression qui ne peut être évalué qu'au moment de l'exécution.
Initialisation statique, c'est quand l'initialiseur est connu statiquement et aucun constructeur a besoin pour fonctionner. (Initialisation statique est soit zéro-initialisation ou constante d'initialisation.) C'est le cas pour votre
int
variables constante de l'initialiseur, et vous avez la garantie que ceux-ci sont en effet initialisé dans la phase statique.(Statique-stockage de variables dynamiques d'initialisation sont aussi zéro initialzed statiquement avant que quelque chose d'autre se passe.)
Le point crucial est que la statique de la phase d'initialisation se complique pas "exécuter" à tous. Les données sont là dès le début. Cela signifie qu'il n'y a pas de "commande" ou toute autre propriété dynamique que les préoccupations initialisation statique. Les valeurs initiales sont codés en dur dans votre programme binaire, si vous voulez.
Comme vous le dites, cela se produit avant le démarrage du programme, c'est à dire avant
main
commence. C ne précise pas davantage; en C++, cela n'arrive qu'au cours de la statique de la phase d'initialisation avant les objets avec plus compliqué constructeurs ou initialisers.Généralement, les non-zéro, les valeurs sont stockées dans un segment de données dans le fichier du programme, tandis que les valeurs nulles sont dans un bss segment qui vient de réserves suffisamment de mémoire pour les variables. Lorsque le programme démarre, le segment de données est chargé dans la mémoire et la bss segment est défini à zéro. (Bien sûr, la langue standard ne précise pas cela, donc un compilateur pourrait faire autre chose, comme de générer du code pour initialiser chacune des variables avant l'exécution
main
).Reformulation de la norme:
Toutes les variables qui n'ont pas de dynamique de la durée de stockage, n'ont pas de thread local storage durée, et ne sont pas locaux, ont statique de la durée de stockage. En d'autres termes, toutes les variables globales ont statique de la durée de stockage.
Objets statiques, dynamiques d'initialisation ne sont pas nécessairement créé avant la première instruction de la fonction principale. Elle est définie par l'implémentation de savoir si ces objets sont créés avant la première instruction dans les principaux, ou avant la première utilisation de n'importe quelle fonction ou une variable définie dans la traduction même unité que la variable statique pour être initialisé.
Donc, dans votre code, global_int1 et static_int1 sont certainement initialisé avant la première instruction dans le main car ils sont statiquement initialisé. Cependant, global_int2 et static_int2 sont dynamiquement initialisé, afin de leur initialisation de la mise en œuvre est définie conformément à la règle, je l'ai mentionné ci-dessus.
Quant à votre deuxième point, je ne suis pas sûr que je comprends ce que tu veux. Pourriez-vous préciser?