Eu sou novo no Delphi, e tenho executado alguns testes para ver quais variáveis de objeto e variáveis 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 estou acostumado em outras linguagens, mas estou me perguntando se é seguro confiar nele no Delphi? Por exemplo, estou me perguntando se isso pode depender de uma configuração do compilador ou talvez funcionar de forma diferente em máquinas diferentes. É normal confiar em valores inicializados padrão para objetos ou você define explicitamente todas as variáveis de instância no construtor?
Quanto às variáveis da pilha (nível de procedimento), meus testes estão mostrando que os booleanos unitializados são verdadeiros, os inteiros unitializados são 2129993264 e os objetos não inicializados são apenas ponteiros inválidos (ou seja, não nulo). Estou supondo que a norma é sempre definir variáveis de nível de procedimento antes de acessá-los.
Respostas:
Sim, este é o comportamento documentado:
Os campos de objeto são sempre inicializados com 0, 0,0, '', False, nil ou o que for aplicável.
Variáveis globais são sempre inicializadas com 0 etc também;
Variáveis contadas por referência local * são sempre inicializadas com nil ou '';
Variáveis locais não contadas por referência * não são inicializadas, portanto, você deve atribuir um valor antes de usá-las.
Lembro-me de que Barry Kelly em algum lugar escreveu uma definição para "contagem de referência", mas não consigo mais encontrá-la, então isso deve servir enquanto isso:
Notas:
record
em si não é suficiente para se tornar contado por referênciafonte
TObject.Create
, que é um método void, mas noclass function TObject.InitInstance(Instance: Pointer): TObject;
qual é SEMPRE chamado antes de qualquer chamada do construtor, mesmo para versões mais antigas do Delphi. Seu comentário é IMHO errado e confuso.Variáveis globais que não possuem um inicializador explícito são alocadas na seção BSS do executável. Na verdade, eles não ocupam nenhum espaço no EXE; a seção BSS é uma seção especial que o sistema operacional aloca e limpa para zero. Em outros sistemas operacionais, existem mecanismos semelhantes.
Você pode depender de variáveis globais sendo inicializadas com zero.
fonte
Os campos de classe são o padrão zero. Isso está documentado para que você possa confiar nele. As variáveis da pilha local são indefinidas, a menos que string ou interface sejam definidas como zero.
fonte
Apenas como uma observação lateral (já que você é novo no Delphi): Variáveis globais podem ser inicializadas diretamente ao serem declaradas:
fonte
Aqui está uma citação de Ray Lischners Delphi in a Nutshell Capítulo 2
É verdade que variáveis locais no escopo precisam ser inicializadas ... Eu trataria o comentário acima de que "Variáveis globais são inicializadas" como duvidoso até que seja fornecido com uma referência - eu não acredito nisso.
editar ... Barry Kelly diz que você pode contar com eles sendo inicializados em zero, e como ele está na equipe de compiladores do Delphi, acredito que isso se mantém :) Obrigado Barry.
fonte
Variáveis globais e dados de instância de objeto (campos) são sempre inicializados com zero. Variáveis locais em procedimentos e métodos não são inicializados no Win32 Delphi; seu conteúdo é indefinido até que você atribua a eles um valor no código.
fonte
Mesmo que um idioma ofereça inicializações padrão, não acredito que você deva confiar neles. A inicialização com um valor torna isso muito mais claro para outros desenvolvedores que podem não saber sobre inicializações padrão na linguagem e evita problemas entre compiladores.
fonte
Do arquivo de ajuda do Delphi 2007:
ms-help: //borland.bds5/devcommon/variables_xml.html
fonte
Eu tenho uma pequena reclamação com as respostas dadas. Delphi zera o espaço de memória dos globais e dos objetos 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 for um valor legal ??
fonte
TOneTwoThree = (One=1, Two=2, Three=3);
As variáveis inline recentemente introduzidas (desde o Delphi 10.3) estão tornando o controle dos valores iniciais mais fácil.
fonte