2008-09-25 15 views
84

Soy nuevo en Delphi, y he estado corriendo algunas pruebas para ver qué objeto las variables y la pila de las variables se inicializan a por defecto:¿Las variables delphi se inicializan con un valor predeterminado?

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

Este es el comportamiento que estoy acostumbrado a otros idiomas , pero me pregunto si es seguro confiar en Delphi. Por ejemplo, me pregunto si podría depender de una configuración de compilador, o tal vez funcionar de manera diferente en diferentes máquinas. ¿Es normal confiar en los valores inicializados por defecto para los objetos, o establece explícitamente todas las variables de instancia en el constructor?

En cuanto a la pila (Procedimiento de nivel) las variables, mis pruebas están mostrando que no inicializado booleanos son verdaderas, son números enteros no inicializado 2129993264, y los objetos son sólo uninialized punteros no válidos (es decir, no nula). Supongo que la norma es establecer siempre las variables de nivel de procedimiento antes de acceder a ellos?

+1

Dos notas: 1. Los registros no se inicializan. 2. Las variables de referencia contadas siempre se inicializan. !¡PERO! en una función que devuelve una cadena, 'Resultado' no se inicializa en una cadena vacía como es de esperar. Esto se debe a que 'Result' no es una var. Local Entonces, siempre hazlo: Resultado: = ''; – Ampere

+0

también vea: [¿Qué variables se inicializan cuando está en Delphi?] (Http://stackoverflow.com/questions/861045/which-variables-are-initialized-when-in-delphi) – Ampere

Respuesta

89

Sí, este es el comportamiento documentado:

  • campos objeto siempre se inicializan a 0, 0,0, '', Falso, nula o lo que sea aplicable.

  • Las variables globales siempre se inicializan a 0, etc.

  • Las variables locales contadas con referencia * siempre se inicializan a nil o '';

  • Las variables locales no contadas-de-referencia * no están inicializadas, por lo que debe asignar un valor antes de poder usarlas.

Recuerdo que Barry Kelly algún lugar escribió una definición de "referencia contada", pero no lo encuentro nada más, por lo que este debe hacer mientras tanto:

== referencia contado que son a sí mismos de referencia contado, o contiene directa o indirectamente campos (por registros) o elementos (por arrays) que son de referencia contado como: string, variant, interface o matriz dinámica o estáticas matriz containi ng tales tipos.

Notas:

  • record sí mismo no es suficiente para convertirse en referencia contado
  • No he probado esto con los genéricos sin embargo
+2

Como señaló Giacomo en los comentarios a continuación, todo esto se explica en los archivos de ayuda de Delphi en ms-help: //borland.bds4/bds4ref/html/Variables.htm. En Delphi 2009 encontré la misma información buscando en la ayuda "variables" (curiosamente, probé muchas búsquedas, pero no pensé en probarla). –

+8

Las variables locales se inicializan ($ 0) si son de un tipo administrado como cadenas, interfaces, matrices dinámicas o variantes –

+2

Si esta es 'la' respuesta, creo que alguien debe agregar para qué complementos se inicializan las enumeraciones. –

17

Los campos de clase son cero por defecto. Esto está documentado para que pueda confiar en él. Los objetos almacenados de la pila local no están definidos a menos que sean cadena o interfaz, estos se establecen en cero.

+0

Gracias. "Zero" me confunde un poco, ¿eso significa que las cadenas son '', y las interfaces son nulas? –

+4

Sí, exactamente eso. nil = 0 (en el nivel del ensamblador) y '' = nil (convención Delphi). – gabr

+0

¡Salud! ¡Eso tiene sentido, gracias! –

4

Las variables globales y el objeto de datos de instancia (campos) siempre se inicializan a cero. Las variables locales en procedimientos y métodos no se inicializan en Win32 Delphi; su contenido no está definido hasta que les asigne un valor en el código.

2

Incluso si un idioma ofrece inicializaciones predeterminadas, no creo que deba confiar en ellas.Inicializar a un valor lo hace mucho más claro para otros desarrolladores que quizás no conozcan las inicializaciones predeterminadas en el lenguaje y evita problemas entre los compiladores.

+3

Por supuesto que puede. Y deberías. Inicializar todo en 0/''/false/nil en cada constructor es simplemente innecesario. La inicialización de variables globales, por otro lado, no es tan estúpida; por una vez, nunca puedo recordar si se han inicializado o no (ya que no los estoy usando demasiado). – gabr

+1

Si Delphi le permite inicializar una variable en el mismo punto en que la declara (por ejemplo, var fObject: TObject = nil) me inclino a aceptar que la inicialización a un valor es probablemente una buena idea. Pero para mí, parece demasiado hacer eso en el constructor para cada campo de objeto. –

8

Aquí es una cita de Ray Lischners Delphi en una cáscara de nuez Chapter 2

"Cuando Delphi crea primero un objeto, todos los campos comienza a cabo vacía, es decir, los punteros se inicializan a cero, cadenas y matrices dinámicas están vacías, números tienen el valor cero, campos booleanos son falsas, y las variantes se establecen en No asignado. (Ver newInstance y InitInstance en el Capítulo 5 para más detalles.)"

es cierto que las variables locales-en-alcance necesitan para ser inicializado ... trataría el comentario anterior que "las variables globales son iniciadas lised "como dudoso hasta que se proporcione una referencia, no lo creo".

Editar ... Barry Kelly dice que puedes confiar en que no se inicialicen por completo, y dado que está en el equipo de compilador de Delphi, creo que está parado :) Gracias Barry.

+0

En delphi 2006 puede encontrarlo aquí: ms-help: //borland.bds4/bds4ref/html/Variables.htm "Si no inicializa explícitamente una variable global, el compilador la inicializa a 0. Datos de instancia de objeto (fields) también se inicializan a 0. " –

4

De Delphi archivo de ayuda 2007:

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

"Si no inicializa explícitamente una variable global, que se inicie la compilador a 0. "

3

Tengo una pequeña queja con las respuestas dadas. Delphi elimina el espacio de memoria de los objetos globales y los objetos recién creados. Mientras que NORMALMENTE significa que están inicializados hay un caso en el que no son: tipos enumerados con valores específicos. ¿Qué pasa si el cero no es un valor legal?

+1

Cero es siempre un valor legal, es el 1er valor de la enumeración. puedes verlo con ord (MyFirstEnumValue). –

+0

Devolvería el primer valor en el tipo enumerado. – skamradt

+5

Cero no siempre es un valor legal si asigna explícitamente valores a la enumeración. En ese caso, todavía se inicializa a 0 y tiene un valor ilegal. Pero las enumeraciones son simplemente azúcar sintáctica pintada sobre tipos enteros normales, por lo que esto realmente no rompe nada. Asegúrate de que tu código pueda manejarlo. –

24

Las variables globales que no tienen un inicializador explícito se asignan en la sección BSS en el archivo ejecutable. En realidad, no ocupan espacio en el EXE; la sección BSS es una sección especial que el sistema operativo asigna y borra a cero. En otros sistemas operativos, hay mecanismos similares.

Puede depender de que las variables globales se inicialicen en cero.

15

Así como una nota al margen (como usted es nuevo en Delphi): Las variables globales se puede inicializar directamente al declarar que:

var myGlobal:integer=99; 
Cuestiones relacionadas