web-dev-qa-db-fra.com

Pourquoi les variables globales et statiques sont-elles initialisées à leurs valeurs par défaut?

En C/C++, pourquoi les globaux et les variables statiques sont-ils initialisés aux valeurs par défaut?

Pourquoi ne pas le laisser avec juste des valeurs d'ordures? Y a-t-il des raisons particulières à cela?

60
Xinus
  1. Sécurité : laisser la mémoire seule entraînerait une fuite d'informations provenant d'autres processus ou du noyau.

  2. Efficacité : les valeurs sont inutiles jusqu'à ce qu'elles soient initialisées à quelque chose, et il est plus efficace de les mettre à zéro dans un bloc avec des boucles déroulées. Le système d'exploitation peut même mettre à zéro les pages de liste libre lorsque le système est autrement inactif, plutôt que lorsqu'un client ou un utilisateur attend le démarrage du programme.

  3. ( Reproductibilité : laisser les valeurs seules rendrait le comportement du programme non répétable, rendant les bugs vraiment difficiles à trouver.

  4. Élégance : c'est plus propre si les programmes peuvent commencer à partir de 0 sans avoir à encombrer le code avec les initialiseurs par défaut.

On peut alors se demander pourquoi la classe de stockage auto commence comme une ordure. La réponse est double:

  1. Ce n'est pas le cas dans un sens. La toute première page de cadre de pile à chaque niveau (c'est-à-dire chaque nouvelle page ajoutée à la pile) ne reçoit aucune valeur. Les valeurs "garbage" ou "non initialisées" que voient les instances de fonction suivantes au même niveau de pile sont vraiment les valeurs précédentes laissées par les autres instances de méthode de votre propre programme et de sa bibliothèque.

  2. Il peut y avoir un quadratique (ou autre) pénalité de performance d'exécution associé à l'initialisation de auto (fonction locale) à n'importe quoi. Une fonction peut ne pas utiliser tout ou partie d'un grand tableau, par exemple, lors d'un appel donné, et elle peut être invoquée des milliers ou des millions de fois. L'initialisation de la statique et des globaux, OTOH, ne doit se produire qu'une seule fois.

68
DigitalRoss

Parce qu'avec la bonne coopération du système d'exploitation, 0 l'initialisation des statiques et des globaux peut être implémentée sans surcharge d'exécution.

24
R Samuel Klatchko

La section 6.7.8 Initialisation de la norme C99 (n1256) répond à cette question:

Si un objet qui a une durée de stockage automatique n'est pas initialisé explicitement, sa valeur est indéterminée. Si un objet qui a une durée de stockage statique n'est pas initialisé explicitement, alors:

- s'il a un type de pointeur, il est initialisé à un pointeur nul;

- s'il a un type arithmétique, il est initialisé à zéro (positif ou non signé);

- s'il s'agit d'un agrégat, chaque membre est initialisé (récursivement) selon ces règles;

- s'il s'agit d'une union, le premier membre nommé est initialisé (récursivement) selon ces règles.

17
Jingguo Yao

Pensez-y, dans le domaine statique, vous ne pouvez pas toujours dire avec certitude que quelque chose est effectivement initialisé ou que le principal a commencé. Il y a aussi un init statique et une phase d'initialisation dynamique, la première statique juste après la dynamique où l'ordre est important.

Si vous n'aviez pas mis à zéro la statique, vous seriez complètement incapable de dire dans cette phase si quelque chose a été initialisé AT ALL et en bref, le monde C++ se séparerait et les choses de base comme les singletons (ou toute sorte d'init statique statique) cesseraient simplement de fonctionner.

La réponse avec les puces est enthousiaste mais un peu idiote. Celles-ci pourraient toutes s'appliquer à une allocation non statique mais cela n'est pas fait (enfin, parfois mais pas habituellement).

6
Charles Eli Cheese

En C, les objets alloués statiquement sans initialiseur explicite sont initialisés à zéro (pour les types arithmétiques) ou à un pointeur nul (pour les types de pointeurs). Les implémentations de C représentent généralement des valeurs nulles et des valeurs de pointeur nul en utilisant un modèle de bits composé uniquement de bits de valeur nulle (bien que cela ne soit pas requis par la norme C). Par conséquent, la section bss comprend généralement toutes les variables non initialisées déclarées à la portée du fichier (c'est-à-dire en dehors de toute fonction) ainsi que les variables locales non initialisées déclarées avec le mot clé statique.

Source: Wikipedia

3
Anant Simran Singh