11
votes

initialisation variable statique?

Je veux savoir pourquoi exactement des variables statiques en C, C ++ et Java sont initialisées par zéro par défaut? Et pourquoi cela n'est pas vrai pour les variables locales?


3 commentaires

De quelle langue parlez-vous?


Ce n'est pas spécifique à la langue, mais tout au sujet de concepts? Dans toutes les langues C, C ++, Java, l'initialisation par défaut de la variable statique est nulle


Non, la tonne, les variables statiques sont initialisées par défaut.


7 Réponses :


5
votes

paragraphe 8.5.6 de la norme standard C ++ indique:

"Chaque objet de la durée de stockage statique doit être initialisé zéro au démarrage du programme"

(la norme indique également que l'initialisation des variables locales est indéfinie)

Pourquoi, la norme ne dit pas;) Une seule estimation est que c'est raisonnablement facile à mettre en œuvre sans descente supplémentaire.


4 commentaires

Il veut probablement savoir pourquoi ce choix a été fait.


Oui c'est vrai, mais ma question est pourquoi?


Et le côté bascule est que l'initialisation par défaut des locaux entraînerait une performance. Et les concepteurs C ++ sont plus concentrés sur la performance que la facilité d'écriture de programmes corrects.


Stephen C, pas tant de performance que le contrôle des performances. Et non seulement la performance. Cela facilite réellement écrire des programmes corrects à long terme ;-)



3
votes

Parler pour Java:

Les variables locales doivent être initialisées avant de pouvoir y accéder, car c'est un gain de sécurité. Le compilateur vérifie pour vous si la variable est définitivement définie.

Les variables statiques ou de classe (avec un type d'objet) sont initialisées avec null , car le compilateur ne peut pas vérifier s'ils sont initialisés au moment de la compilation. Au lieu de laisser le programme échouer s'il accède à une variable non initialisée, elle sera initialisée implicite avec null .

variables avec un type natif Impossible d'obtenir une valeur null , de sorte que les variables non locales sont initialisées avec 0 ou false , comme une baisse. Ce n'est pas la meilleure solution, bien sûr, mais je ne sais pas un meilleur. ; -)


3 commentaires

En fait, du point de vue JVM, la variable locale n'existe tout simplement qu'à l'initialisation.


Le compilateur vérifie que les champs finaux sont attribués et non évidemment utilisés avant d'être attribués. Cependant, il existe toujours des moyens de voir les champs avant les affectations (pas vraies avec les locaux). Les champs statiques non finaux devraient être extrêmement rares ( Devraient ). Il quitte pourquoi il n'est pas considéré comme une erreur probablement de laisser un champ avec la valeur par défaut.


@TOM - La réponse à votre question "ouverte" est qu'il serait extrêmement difficile de proposer des règles JLS pour cela que 1) ne nécessite pas d'analyse de toutes les classes dans un programme et 2) faire face à une chargement dynamique.



0
votes

C'est juste une supposition, mais cela pourrait être la façon dont il est pour la statique car il est facile à mettre en œuvre et utile.

Le compilateur peut co-allouer toutes les variables dans une zone de mémoire contiganeuse, puis émettrice Code (un seul MEMSET () appel) Pour effacer-le avant Main () est appelé. Dans de nombreux cas, il peut également s'appuyer sur des fonctionnalités du format de fichier exécutable du système d'exploitation, si ce format prend en charge " BSS Sections ", qui sont effacées par le chargeur à la place. Cela permet d'économiser de l'espace dans l'exécutable, vous pourriez avoir xxx

et l'exécutable ne se développerait pas par un mégaoctet.

pour les variables locales, aucune de ces applications ne s'applique ; Ils sont alloués "à la volée" (typiquement sur une pile) et ce serait un gaspillage de ressources pour les effacer, car ils vont généralement être affectés à très bientôt.


0 commentaires

1
votes

Je n'ai aucune idée de Java et je doute que ce soit différent pour les statiques / locaux en Java.

As comme pour C et C ++, il s'agit de programmer des programmeurs sur leur effet de code et d'aimer être en contrôle. L'initialisation des variables locales impliquerait l'exécution d'un code supplémentaire à chaque programme de temps entre dans la portée. Pour des fonctions fréquemment appelées qui peuvent être une catastrophe.


7 commentaires

Bien écrit, mais ce n'est pas une réponse à ma question


Je ne sais pas ce que tu veux. Si vous rejetez cela, je vous attends à ce que vous acceptiez la réponse andreas. Il cite la norme et je vous donne la raison derrière elle. Quelle réponse cherchez-vous?


Cela suppose que les compilateurs sont vraiment stupides. Dans presque tous les cas, il est facile de voir si une variable est attribuée avant utilisation.


De quoi cela a-t-il à voir avec l'hypothèse que vous m'accusez?


@hacker, je veux savoir pourquoi exactement les variables statiques sont initialisées par zéro?


Ah, Sachin, je pensais que vous demandez pourquoi la différence. Vous avez donc une question pourquoi sont-ils initialisés ou pourquoi zéro? C'est souvent pratique. Pour la même raison, Calloc le fait, mais Malloc existe.


Heh, Sachin, j'aime la question, mais je ne pense pas qu'il y ait une réponse pare-balles. Je dirais que zéro octets vous fournirait la même valeur zéro pour tous les types fondamentaux.



2
votes

Donc, dans une certaine mesure, il ne s'agit que de décisions de conception de la part des concepteurs de la langue. Mais les raisons probables de ces décisions en Java sont les suivantes:

  • pour les variables statiques / membres, si vous allez les initialiser à quelque chose, alors zéro est une valeur commode car (a) c'est généralement une valeur appropriée pour signifier "non définie pour rien d'autre spécial", et est la valeur Vous auriez choisi de toute façon dans certains cas tels que des compteurs; et (b) en interne, il est probable que zéro peut être utilisé pour des valeurs "spéciales", notamment pour représenter NULL dans le cas d'une référence d'objet.
  • pour les variables locales, ce qui ne leur donne aucune valeur par défaut ne permet à la règle qui oblige le programmateur à définir une certaine valeur avant que la variable soit lue, ce qui puisse être utile pour permettre au compilateur de repérer certaines erreurs.

    Dans le cas des variables locales, il est également concevable qu'une variable locale pouvait être déclarée (qui, au niveau du code de code bytecode / de la machine, signifie essentiellement l'affectation d'espace de pile / déplacement du pointeur de pile), mais jamais jamais écrit / lu dans un particulier Chemin de code. Donc, ne pas avoir de défaut évite de faire un travail inutile de définir une défaillance dans ces cas.

    Je répète, cependant, ils sont des décisions de conception dans une certaine mesure. Ils sont essentiellement un compromis entre ce qui sera probablement pratique pour les implémentations JVM et pratique pour les programmeurs.

    n.b. En C / C ++, les variables "statiques" signifient une chose différente pour les variables statiques en Java!


0 commentaires

21
votes

pourquoi les variables statiques sont déterminées de manière déterministe et les variables locales ne sont pas?

Voyez comment les variables statiques sont implémentées. La mémoire d'entre eux est allouée à l'heure de liaison, et la valeur initiale pour eux est également fournie au moment de la liaison. Il n'y a pas de surcharge d'exécution.

D'autre part, la mémoire des variables locales est attribuée au moment de l'exécution. La pile doit grandir. Vous ne savez pas ce qui était là avant. Si vous le souhaitez, vous pouvez effacer cette mémoire (zéro), mais cela entraînerait une surcharge d'exécution. La philosophie C ++ est "Vous ne payez pas pour des choses que vous n'utilisez pas", donc il ne zéro pas de la mémoire par défaut.

ok, mais pourquoi les variables statiques sont-elles initialisées à zéro et non une autre valeur?

Eh bien, vous voulez généralement faire quelque chose avec cette variable. Mais alors comment savez-vous s'il a été initialisé? Vous pouvez créer une variable booléenne statique. Mais alors il doit également être initialisé de manière fiable à quelque chose (de préférence faux). que diriez-vous d'un pointeur? Vous préférez le vouloir initialiser à NULL que des ordures aléatoires. Que diriez-vous d'une structure / enregistrement? Il a quelques autres membres de données à l'intérieur. Il est logique de les initialiser à toutes les valeurs par défaut. Mais pour la simplicité, si vous utilisez la stratégie "Initialiser à 0", vous n'avez pas à inspecter les membres individuels et à vérifier leurs types. Vous pouvez simplement initialiser la zone de mémoire entière à 0.

Ce n'est pas vraiment une exigence technique. La sémantique de l'initialisation pourrait toujours être considérée comme sain d'esprit si la valeur par défaut est autre chose que 0, mais toujours déterministe. Mais alors, quelle devrait être cette valeur? Vous pouvez facilement expliquer pourquoi 0 est utilisé (bien qu'il semble légèrement arbitraire), mais expliquant -1 ou 1024 semble être encore plus difficile (surtout que la variable peut ne pas être suffisamment grande pour maintenir cette valeur, etc.).

Et vous pouvez toujours initialiser la variable explicitement.

Et vous avez toujours le paragraphe 8.5.6 de la norme C ++ qui dit "chaque objet de la durée de stockage statique doit être initialisé zéro au démarrage du programme".

Pour plus d'informations, veuillez vous reporter à ces autres questions:


4 commentaires

Oui, j'ai convenu que la mémoire des variables statiques est allouée à l'heure de liaison, mais pourquoi elle est zéro par défaut.


J'ai développé ma réponse, espérons-le que cela a l'informe qui vous intéresse.


Qu'en est-il d'un objet de classe, sûr que son constructeur ne soit pas appelé au moment de la liaison, puis s'il est initialisé dans le temps de liaison, il est simplement initialisé en tant que pod, ce qui semble avoir aucun sens?


la mémoire pour eux [Variables statiques] est allouée à l'heure de liaison [Ceci peut dépendre de la plate-forme] - Ce n'est pas vraiment le cas, mais plutôt au moment de la charge, lorsque le binaire est chargé en mémoire. . En particulier, pour les valeurs non nulles, le binaire doit contenir la valeur [rendant le binaire plus grand], mais pour des valeurs zéro, il n'est pas nécessaire de ne pas contenir la variable du tout, il doit simplement informer le chargeur pour réserver une place [une taille unique pour tous statique zéro des vars suffit aux suffisants]. Ceci est également lié à la valeur zéro , ce n'est pas arbitraire du tout. De plus, de nombreux OS-S ont déjà nul le souvenir pour vous.



1
votes

Cela concerne le concept de "seulement payer pour ce que vous utilisez" en C / C ++.

Pour les variables statiques, une initialisation peut être faite sans génération de code. Le fichier d'objet contient les valeurs initiales des variables dans le segment de données et lorsque le système d'exploitation charge l'exécutable chargé et mappe ce segment de données avant que le programme ne commence à exécuter.

Pour les variables locales Il n'y a aucun moyen de les initialiser sans code car ils ne sont pas initialisés une fois, ils doivent être initialisés à chaque fois que vous entrez dans leur champ d'application; De plus, ils sont alloués dans la pile et lorsque l'allocation survient la valeur initiale de la pile dans le cas général est simplement ce qui était là auparavant (à l'exception de ces rares moments que vous cultivez la pile plus que cela n'a grandi avant).

Pour initialiser implicitement une variable locale, le compilateur devrait générer du code sans le programmeur le commandant explicitement de le faire, ce qui est tout à fait contre cette "philosophie".

À propos de Java, autant que je sache, les variables sont toujours initialisées lorsque le programme entre dans leur portée, peu importe si elles sont statiques ou non. La seule différence significative entre eux est que la portée des variables statiques est l'ensemble du programme. Étant donné que le comportement est cohérent parmi tous.


0 commentaires