2008-09-25 8 views
84

Je suis nouveau à Delphes, et je l'ai couru quelques tests pour voir quelles sont les variables objet et pile variables sont initialisées par défaut:Les variables delphi sont-elles initialisées avec une valeur par défaut?

TInstanceVariables = class 
    fBoolean: boolean; // always starts off as false 
    fInteger: integer; // always starts off as zero 
    fObject: TObject; // always starts off as nil 
end; 

C'est le comportement que je suis habitué à d'autres langues , mais je me demande s'il est sûr de s'en fier Delphi? Par exemple, je me demande si cela pourrait dépendre d'un réglage du compilateur, ou peut-être travailler différemment sur des machines différentes. Est-il normal de s'appuyer sur des valeurs initialisées par défaut pour les objets, ou définissez-vous explicitement toutes les variables d'instance dans le constructeur? Comme pour les variables de pile (niveau de procédure), mes tests montrent que les booléens unitialisés sont vrais, les entiers unitalisés sont 2129993264 et les objets non numérisés sont juste des pointeurs invalides (c'est-à-dire non nul). Je suppose que la norme est de toujours définir les variables au niveau de la procédure avant d'y accéder?

+1

Deux notes: 1. Les dossiers ne sont pas initialisés. 2. Les variables comptées de référence sont toujours initialisées. !MAIS! Dans une fonction qui renvoie une chaîne, 'Result' n'est pas initialisé en chaîne vide comme vous pouvez vous y attendre. C'est parce que 'Result' n'est pas une variable locale. Alors, faites toujours: Résultat: = ''; – Ampere

+0

voir aussi: [Quelles variables sont initialisées en Delphi?] (Http://stackoverflow.com/questions/861045/which-variables-are-initialized-when-in-delphi) – Ampere

Répondre

89

Oui, cela est le comportement documenté:

  • champs d'objets sont toujours initialisées à 0, 0,0, '', Faux, nul ou selon le cas.

  • Les variables globales sont toujours initialisées à 0, etc.

  • Les variables locales comptées par référence * sont toujours initialisées à zéro ou '';

  • Les variables locales non comptées * ne sont pas initialisées. Vous devez donc attribuer une valeur avant de pouvoir les utiliser.

Je me souviens que Barry Kelly quelque part a écrit une définition pour « référence compté », mais ne peut pas trouver plus, ce qui devrait faire dans l'intervalle:

== de référence comptés qui sont eux-mêmes compté référence, ou contient directement ou indirectement champs (pour les documents) ou des éléments (par réseaux) qui sont comptées comme référence: string, variant, interface ou tableau dynamique ou tableau statique containi ng de tels types.

Notes:

  • record lui-même ne suffit pas pour devenir référence compté
  • Je n'ai pas essayé avec les génériques encore
+2

Comme Giacomo l'a souligné dans les commentaires ci-dessous, tout cela est expliqué dans les fichiers d'aide de Delphi à ms-help: //borland.bds4/bds4ref/html/Variables.htm. Dans Delphi 2009 j'ai trouvé la même information en cherchant l'aide pour "variables" (curieusement j'ai essayé beaucoup de recherches mais je n'ai pas pensé à essayer celui-là). –

+8

Les variables locales sont initialisées ($ 0) si elles sont de type managé comme les chaînes, les interfaces, les tableaux dynamiques ou les variantes –

+2

Si c'est la réponse, je pense que quelqu'un devrait ajouter les ensembles et enums initialisés. –

17

Les champs de classe ont la valeur zéro par défaut. Ceci est documenté de sorte que vous pouvez compter dessus. Les variables de pile locales ne sont pas définies à moins d'une chaîne ou d'une interface, elles sont définies sur zéro.

+0

Merci. "Zéro" me confond un peu - est-ce que cela signifie que les chaînes sont '', et que les interfaces sont nulles? –

+4

Oui, exactement cela. nil = 0 (au niveau de l'assembleur) et '' = nil (convention Delphi). – gabr

+0

Cheers - c'est logique, merci! –

4

Les variables globales et objet de données d'instance (champs) sont toujours initialisés à zéro. Les variables locales dans les procédures et méthodes ne sont pas initialisées dans Win32 Delphi; leur contenu est indéfini jusqu'à ce que vous leur attribuez une valeur dans le code.

2

Même si une langue offre des initialisations par défaut, je ne pense pas que vous devriez vous y fier.L'initialisation à une valeur le rend beaucoup plus clair pour les autres développeurs qui pourraient ne pas connaître les initialisations par défaut dans le langage et éviter les problèmes entre les compilateurs.

+3

Bien sûr, vous pouvez. Et tu devrais. Initialiser tout à 0/''/false/nil dans chaque constructeur est simplement inutile. Initialiser des variables globales, d'autre part, n'est pas si stupide - pour une fois je ne peux jamais me souvenir si elles sont initialisées ou non (car je ne les utilise pas beaucoup). – gabr

+1

Si Delphi vous permet d'initialiser une variable au même point que vous la déclarez (par exemple var fObject: TObject = nil), je serais enclin à accepter que l'initialisation à une valeur est probablement une bonne idée. Mais pour moi, il semble un peu trop le faire dans le constructeur pour chaque champ d'objet. –

8

Voici une citation de Ray Lischners Delphi dans un Nutshell Chapter 2

« Lorsque Delphi crée d'abord un objet, tous les champs commencent à vide, qui est, les pointeurs sont initialisés à zéro, des chaînes et des tableaux dynamiques sont vides, les chiffres ont la valeur zéro, les champs booléens sont faux, et les variantes sont mis à Unassigned. (Voir NewInstance et InitInstance au chapitre 5 pour plus de détails.) »

Il est vrai que les variables locales en champ doivent être initialisé ... Je traiterais le commentaire ci-dessus que "Les variables globales sont initia lised "comme douteux jusqu'à fourni avec une référence - je ne crois pas cela. Barry Kelly dit que vous pouvez compter sur eux étant zéro-initialisé, et depuis qu'il est sur l'équipe de compilateur Delphi, je crois que cela reste :) Merci Barry.

+0

Dans delphi 2006, vous pouvez le trouver ici: ms-help: //borland.bds4/bds4ref/html/Variables.htm "Si vous n'initialisez pas explicitement une variable globale, le compilateur l'initialise à 0. Données d'instance d'objet (les champs) sont également initialisés à 0. " –

4

De Delphi 2007 fichier d'aide:

ms-help: //borland.bds5/devcommon/variables_xml.html

« Si vous n'initialise pas explicitement une variable globale, les compilateur Initialise à 0. "

3

J'ai un petit reproche avec les réponses données. Delphi met à zéro l'espace mémoire des globales et des objets nouvellement créés. Bien que ce NORMALEMENT signifie qu'ils sont initialisés il y a un cas où ils ne sont pas: types énumérés avec des valeurs spécifiques. Et si zéro n'est pas une valeur légale ??

+1

Zéro est toujours une valeur légale, c'est la 1ère valeur de l'énumération. vous pouvez le voir avec ord (MyFirstEnumValue). –

+0

Il retournera la première valeur dans le type énuméré. – skamradt

+5

Zéro n'est pas toujours une valeur légale si vous attribuez explicitement des valeurs à l'énumération. Dans ce cas, il est toujours initialisé à 0 et vous avez une valeur illégale. Mais les enums ne sont que du sucre syntaxique peint sur des types entiers normaux, donc cela ne casse vraiment rien. Assurez-vous que votre code peut gérer cela. –

24

Les variables globales qui n'ont pas d'initialiseur explicite sont allouées dans la section BSS de l'exécutable. Ils n'occupent aucun espace dans l'EXE; la section BSS est une section spéciale que l'OS alloue et efface à zéro. Sur d'autres systèmes d'exploitation, il existe des mécanismes similaires.

Vous pouvez compter sur l'initialisation zéro des variables globales.

15

Tout comme une note de côté (comme vous êtes nouveau à Delphi): Les variables globales peuvent être initialisés directement en les déclarant:

var myGlobal:integer=99; 
Questions connexes