Soy nuevo en Delphi y he estado ejecutando algunas pruebas para ver qué variables de objeto y variables de pila se inicializan de forma predeterminada:
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 al que estoy acostumbrado en otros idiomas, pero me pregunto si es seguro confiar en él en Delphi. Por ejemplo, me pregunto si podría depender de la configuración de un compilador o quizás funcionar de manera diferente en diferentes máquinas. ¿Es normal confiar en los valores inicializados predeterminados para los objetos o establece explícitamente todas las variables de instancia en el constructor?
En cuanto a las variables de pila (nivel de procedimiento), mis pruebas muestran que los valores booleanos unitarios son verdaderos, los enteros unitarios son 2129993264 y los objetos no inicializados son solo punteros no válidos (es decir, no nulos). Supongo que la norma es establecer siempre variables a nivel de procedimiento antes de acceder a ellas.
fuente
Respuestas:
Sí, este es el comportamiento documentado:
Los campos de objeto siempre se inicializan en 0, 0.0, '', False, nil o lo que corresponda.
Las variables globales siempre se inicializan en 0, etc. también;
Las variables locales contadas por referencias * siempre se inicializan en cero o '';
Las variables locales que no cuentan con referencias * no están inicializadas, por lo que debe asignar un valor antes de poder usarlas.
Recuerdo que Barry Kelly en algún lugar escribió una definición de "referencia contada", pero ya no puedo encontrarla, así que esto debería funcionar mientras tanto:
Notas:
record
en sí mismo no es suficiente para convertirse en referencia contadafuente
TObject.Create
, que es un método vacío, pero en elclass function TObject.InitInstance(Instance: Pointer): TObject;
que SIEMPRE se llama antes de cualquier llamada al constructor, incluso para versiones anteriores de Delphi. En mi humilde opinión, su comentario es incorrecto y confuso.Las variables globales que no tienen un inicializador explícito se asignan en la sección BSS del 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, existen mecanismos similares.
Puede depender de que las variables globales se inicialicen a cero.
fuente
Los campos de clase son cero por defecto. Esto está documentado para que pueda confiar en él. Las variables de pila local no están definidas a menos que la cadena o la interfaz se establezcan en cero.
fuente
Solo como nota al margen (ya que es nuevo en Delphi): las variables globales se pueden inicializar directamente al declararlas:
fuente
Aquí hay una cita de Ray Lischner Delphi in a Nutshell Capítulo 2
Es cierto que las variables locales en el alcance deben inicializarse ... Trataría el comentario anterior de que "Las variables globales se inicializan" como dudoso hasta que se proporcione una referencia; no lo creo.
editar ... Barry Kelly dice que puede depender de que se inicialicen a cero, y dado que él está en el equipo del compilador de Delphi, creo que se mantiene :) Gracias Barry.
fuente
Las variables globales y los datos de instancia de objeto (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.
fuente
Incluso si un idioma ofrece inicializaciones predeterminadas, no creo que deba confiar en ellas. Inicializar a un valor hace que sea mucho más claro para otros desarrolladores que podrían no conocer las inicializaciones predeterminadas en el lenguaje y evita problemas entre los compiladores.
fuente
Desde el archivo de ayuda de Delphi 2007:
ms-help: //borland.bds5/devcommon/variables_xml.html
fuente
Tengo una pequeña queja con las respuestas dadas. Delphi pone a cero el espacio de memoria de los globales y los objetos recién creados. Si bien esto NORMALMENTE significa que están inicializados, hay un caso en el que no lo son: tipos enumerados con valores específicos. ¿Y si cero no es un valor legal?
fuente
TOneTwoThree = (One=1, Two=2, Three=3);
Las variables en línea recién introducidas (desde Delphi 10.3) están facilitando el control de los valores iniciales.
fuente