As variables ​​delphi são inicializadas com um valor por padrão?

Sou novo no Delphi e tenho feito alguns testes para ver por quais variables ​​de object e variables ​​de pilha são inicializadas por padrão:

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 é o comportamento que eu estou acostumado em outros idiomas, mas eu estou querendo saber se é seguro confiar nele no Delphi? Por exemplo, eu estou querendo saber se pode depender de uma configuração de compilador, ou talvez trabalhar de forma diferente em máquinas diferentes. É normal confiar em valores inicializados padrão para objects ou você define explicitamente todas as variables ​​de instância no construtor?

Quanto às variables ​​de pilha (nível de procedimento), meus testes estão mostrando que booleanos unitializados são verdadeiros, inteiros unitializados são 2129993264 e objects não inicializados são apenas pointers inválidos (ou seja, não são nulos). Eu estou supondo que a norma é sempre definir variables ​​de nível de procedimento antes de acessá-los?

Sim, este é o comportamento documentado:

  • Campos de object são sempre inicializados para 0, 0.0, ”, Falso, nulo ou o que for aplicável.

  • Variáveis ​​globais são sempre inicializadas para 0 etc também;

  • Variáveis ​​locais de referência * são sempre inicializadas como nulas ou ”;

  • As variables ​​locais não contadas por referência * não são inicializadas, portanto você deve atribuir um valor antes de poder usá-las.

Eu lembro que Barry Kelly em algum lugar escreveu uma definição para “referência contada”, mas não pode mais encontrá-la, então isso deve acontecer enquanto isso:

contados por referência == que são contados por referência em si, ou direta ou indiretamente contêm campos (para registros) ou elementos (para matrizes) que são contados por referência como: string, variant, interface ou matriz dinâmica ou matriz estática contendo tais tipos.

Notas:

  • record si não é suficiente para se tornar referência contada
  • Eu não tentei isso com genéricos ainda

Variáveis ​​globais que não possuem um inicializador explícito são alocadas na seção BSS no executável. Eles realmente não ocupam espaço no EXE; a seção BSS é uma seção especial que o SO aloca e limpa para zero. Em outros sistemas operacionais, existem mecanismos semelhantes.

Você pode depender de variables ​​globais que são inicializadas com zero.

Campos de class são o padrão zero. Isso está documentado para que você possa confiar nele. Variáveis ​​locais de pilha são indefinidas, a menos que seja uma string ou interface, elas são definidas como zero.

Apenas como uma nota lateral (como você é novo no Delphi): Variáveis ​​globais podem ser inicializadas diretamente ao declará-las:

 var myGlobal:integer=99; 

Aqui está uma citação de Ray Lischners Delphi in a Nutshell Chapter 2

“Quando o Delphi primeiro cria um object, todos os campos começam vazios, isto é, os pointers são inicializados como inexistentes, os strings e arrays dynamics são vazios, os números têm o valor zero, os campos booleanos são False e Variantes são definidos como Não atribuídos. (Veja NewInstance e InitInstance no Capítulo 5 para detalhes.) ”

É verdade que as variables ​​locais no escopo precisam ser inicializadas … Eu trataria o comentário acima que “Variáveis ​​globais são inicializadas” como duvidosas até receberem uma referência – não acredito nisso.

editar … Barry Kelly diz que você pode depender deles serem inicializados com zero, e já que ele está na equipe de compiladores Delphi, eu acredito que isso acontece 🙂 Obrigado Barry.

Variáveis ​​globais e dados de instância de object (campos) são sempre inicializados para zero. Variáveis ​​locais em procedimentos e methods não são inicializadas no Win32 Delphi; seu conteúdo é indefinido até você atribuir um valor ao código.

A partir do arquivo de ajuda do Delphi 2007:

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

“Se você não inicializar explicitamente uma variável global, o compilador inicializa para 0.”

Eu tenho uma pequena reclamação com as respostas dadas. O Delphi zera o espaço de memory dos globals e dos objects recém-criados. Embora isso normalmente signifique que eles foram inicializados, há um caso em que eles não são: tipos enumerados com valores específicos. E se zero não é um valor legal?

Mesmo que uma linguagem ofereça inicializações padrão, não acredito que você deva confiar nelas. A boot para um valor torna muito mais claro para outros desenvolvedores que podem não saber sobre inicializações padrão no idioma e evita problemas em compiladores.