Quelle est l'importance d'initialiser les variables?
Une initialisation correcte évite-t-elle les fuites de mémoire ou présente-t-elle des avantages en termes de performances?
Quelle est l'importance d'initialiser les variables?
Une initialisation correcte évite-t-elle les fuites de mémoire ou présente-t-elle des avantages en termes de performances?
null
) par les compilateurs communs, mais sont des ordures aléatoires lors de la compilation pour la publication. (bien que mes connaissances en C ++Réponses:
Les variables non initialisées rendent un programme non déterministe. Chaque fois que le programme s'exécute, il peut se comporter différemment. Les changements indépendants de l'environnement d'exploitation, de l'heure de la journée, de la phase de la lune et de leurs permutations affectent comment et quand ces démons se manifestent. Le programme peut s'exécuter un million de fois avant la présentation du défaut, il peut le faire à chaque fois ou exécuter un autre million. De nombreux problèmes sont attribués à des "pépins" et ignorés, ou des rapports de défauts de clients fermés comme "non reproductibles". À quelle fréquence avez-vous redémarré une machine pour «résoudre» un problème? Combien de fois avez-vous dit à un client "Je n'ai jamais vu cela se produire, faites-moi savoir si vous le voyez à nouveau" - en espérant (savoir) très bien qu'il ne le fera pas!
Comme la reproduction d'un défaut peut être presque impossible dans l'environnement de test, il est presque impossible de le trouver et de le réparer.
Cela peut prendre des années avant que le bogue n'apparaisse, généralement dans le code considéré comme fiable et stable. Le défaut est supposé être dans un code plus récent - sa recherche peut prendre beaucoup plus de temps. Un changement de compilateur, un commutateur de compilateur, même l'ajout d'une ligne de code peut changer le comportement.
L'initialisation des variables a un énorme avantage en termes de performances, non seulement parce qu'un programme qui fonctionne correctement est infiniment plus rapide que celui qui n'en a pas, mais les développeurs passent moins de temps à rechercher et à corriger les défauts qui ne devraient pas être là et plus de temps à faire un "vrai" travail.
L'autre avantage significatif de l'initialisation des variables est que l'auteur original du code doit décider à quoi les initialiser. Ce n'est pas toujours un exercice trivial, et lorsqu'il n'est pas trivial, il peut être le signe d'une mauvaise conception.
Les fuites de mémoire sont un problème différent, mais une bonne initialisation peut non seulement aider à les prévenir, mais également à les détecter et à trouver la source - sa langue dépend fortement et c'est vraiment une question distincte qui mérite une exploration plus approfondie que celle que je suis en mesure de donner. dans cette réponse.
Edit: Dans certains langages (par exemple C #), il n'est pas possible d'utiliser des variables non initialisées, car le programme ne compilera pas ou ne signalera pas d'erreur lors de son exécution, si cela est fait. Cependant, de nombreux langages avec ces caractéristiques ont des interfaces vers du code potentiellement dangereux, il faut donc faire attention lors de l'utilisation de telles interfaces no pour introduire des variables non initialisées.
la source
L'initialisation d'une variable comme Telastyn l'a souligné peut éviter les bogues. Si la variable est un type de référence, l'initialiser peut éviter des erreurs de référence nulles sur toute la ligne.
Une variable de n'importe quel type qui a une valeur par défaut non nulle prendra de la mémoire pour stocker la valeur par défaut.
la source
Essayer d'utiliser une variable non initialisée est toujours un bug, il est donc logique de minimiser la probabilité que ce bug se produise.
L'approche la plus courante utilisée par les langages de programmation pour atténuer le problème est d'initialiser automatiquement à une valeur par défaut, donc au moins si vous oubliez d'initialiser une variable, ce sera quelque chose comme
0
au lieu de quelque chose comme0x16615c4b
.Cela résout un grand pourcentage de bogues, si vous aviez de toute façon besoin d'une variable initialisée à zéro. Cependant, l'utilisation d'une variable qui a été initialisée à une valeur incorrecte est tout aussi mauvaise que l'utilisation d'une variable qui n'a pas été initialisée du tout. En fait, cela peut parfois être encore pire, car l'erreur peut être plus subtile et difficile à détecter.
Les langages de programmation fonctionnels résolvent ce problème non seulement en interdisant les valeurs non initialisées, mais en interdisant complètement la réaffectation. Cela élimine le problème et s'avère ne pas être une restriction aussi sévère que vous pourriez le penser. Même dans les langages non fonctionnels, si vous attendez pour déclarer une variable jusqu'à ce que vous ayez une valeur correcte pour l'initialiser avec, votre code a tendance à être beaucoup plus robuste.
En ce qui concerne les performances, c'est probablement négligeable. Au pire, avec des variables non initialisées, vous avez une affectation supplémentaire et bloquez de la mémoire plus longtemps que nécessaire. De bons compilateurs peuvent optimiser les différences dans de nombreux cas.
Les fuites de mémoire sont complètement indépendantes, bien que les variables correctement initialisées aient tendance à être à portée pendant une période de temps plus courte, et peuvent donc être un peu moins susceptibles pour un programmeur de fuir accidentellement.
la source
L'initialisation implique que la valeur initiale est importante. Si la valeur initiale est importante, alors oui, vous devez clairement vous assurer qu'elle est initialisée. Si cela n'a pas d'importance, cela implique qu'il sera initialisé plus tard.
Une initialisation inutile entraîne des cycles CPU gaspillés. Bien que ces cycles gaspillés puissent ne pas avoir d'importance dans certains programmes, dans d'autres programmes, chaque cycle est important car la vitesse est la principale préoccupation. Il est donc très important de comprendre quels sont ses objectifs de performance et si les variables doivent être initialisées ou non.
Les fuites de mémoire sont un problème complètement différent qui implique généralement une fonction d'allocation de mémoire pour émettre et recycler ultérieurement des blocs de mémoire. Pensez à un bureau de poste. Vous allez demander une boîte aux lettres. Ils vous en donnent un. Vous en demandez un autre. Ils vous en donnent un autre. La règle est que lorsque vous avez terminé d'utiliser une boîte aux lettres, vous devez la restituer. Si vous oubliez de le rendre, ils pensent toujours que vous l'avez, et la boîte ne peut être réutilisée par personne d'autre. Il y a donc un morceau de mémoire attaché et non utilisé, et c'est ce qu'on appelle une fuite de mémoire. Si vous continuez à demander des boîtes à un moment donné, vous manquerez de mémoire. J'ai simplifié à l'excès, mais c'est l'idée de base.
la source
Comme d'autres l'ont dit, cela dépend de la langue. Mais je vais démontrer mes idées Java (et Java efficace) sur l'initialisation des variables. Ceux-ci devraient être utilisables pour de nombreuses autres langues de niveau supérieur.
Constantes et variables de classe
Les variables de classe - marquées avec
static
en Java - sont comme des constantes. Ces variables doivent normalement être finales et initialisées directement après la définition à l'aide=
ou à partir d'un bloc d'initialisation de classestatic { // initialize here }
.Des champs
Comme dans de nombreux langages de niveau supérieur et de script, une valeur par défaut sera automatiquement attribuée aux champs. Pour les nombres,
char
ce sera la valeur zéro. Pour les cordes et autres objets, ce sera le casnull
. Ilnull
est maintenant dangereux et doit être utilisé avec parcimonie. Ces champs doivent donc être définis sur une valeur valide dès que possible. Le constructeur est normalement un endroit parfait pour cela. Pour vous assurer que les variables sont définies pendant le constructeur, et non modifiées par la suite, vous pouvez les marquer avec lefinal
mot - clé.Essayez de résister à l'envie de l'utiliser
null
comme une sorte de drapeau ou de valeur spéciale. Il est préférable, par exemple, d'inclure un champ spécifique pour conserver l'état. Un champ avec le nomstate
qui utilise les valeurs d'uneState
énumération serait un bon choix.Paramètres de méthode
Étant donné que les modifications des valeurs des paramètres (qu'il s'agisse de références à des objets ou à des types de base tels que des entiers, etc.) ne seront pas vues par l'appelant, les paramètres doivent être marqués comme
final
. Cela signifie que les valeurs de la variable elle-même ne peuvent pas être modifiées. Notez que la valeur des instances d'objets mutables peut être modifiée, la référence ne peut pas être modifiée pour pointer vers un objet différent ounull
bien.Variables locales
Les variables locales ne sont pas automatiquement initialisées; ils doivent être initialisés avant que leur valeur puisse être utilisée. Une méthode pour vous assurer que votre variable est initialisée consiste à les initialiser directement à une sorte de valeur par défaut. C'est cependant quelque chose que vous ne devriez pas faire. La plupart du temps, la valeur par défaut n'est pas une valeur attendue.
Il est préférable de définir uniquement la variable précisément là où vous en avez besoin. Si la variable ne doit prendre qu'une seule valeur (ce qui est vrai pour la plupart des variables dans un bon code), vous pouvez marquer la variable
final
. Cela garantit que la variable locale est affectée exactement une fois, pas zéro fois ou deux fois. Un exemple:Notez que de nombreuses langues vous avertiront si une variable reste non initialisée avant utilisation. Consultez les spécifications linguistiques et les forums pour voir si vous ne vous inquiétez pas inutilement.
la source
Il n'y a aucun problème avec la désinitialisation des variables.
Le problème ne se pose que lorsque vous lisez une variable qui n'a pas encore été écrite.
Selon le compilateur et / ou le type de variable, l'initialisation est effectuée au démarrage de l'application. Ou pas.
Il est courant de ne pas compter sur l'initialisation automatique.
la source
L'initialisation des variables (implicitement ou explicitement) est cruciale. Ne pas initialiser une variable est toujours une erreur (elles peuvent cependant être initialisées implicitement. Voir ci-dessous). Les complices modernes comme le compilateur C # (à titre d'exemple) traitent cela comme une erreur et ne vous permettent pas d'exécuter le code. Une variable non initialisée est simplement inutile et nuisible. À moins que vous ne créiez un générateur de nombres aléatoires, vous attendez d'un morceau de code qu'il produise un résultat déterministe et reproductible. Cela n'est possible que si vous commencez à travailler avec des variables initialisées.
La question vraiment intéressante est de savoir si une variable est initialisée automatiquement ou si vous devez la faire manuellement. Cela dépend de la langue utilisée. En C # par exemple, les champs, c'est-à-dire les "variables" au niveau de la classe, sont toujours automatiquement initialisés à la valeur par défaut pour ce type de variable
default(T)
. Cette valeur correspond à un motif binaire composé de tous les zéros. Cela fait partie de la spécification du langage et pas seulement un détail technique de l'implémentation du langage. Vous pouvez donc vous y fier en toute sécurité. Il est prudent de ne pas initialiser une variable explicitement si (et seulement si) la spécification de langage indique qu'elle est initialisée implicitement.Si vous souhaitez une autre valeur, vous devez initialiser la variable explicitement. Toutefois; en C #, les variables locales, c'est-à-dire les variables déclarées dans les méthodes, ne sont pas initialisées automatiquement et vous devez toujours initialiser la variable explicitement.la source