Fala Pessoal, tudo bem com vocês?
Sabe quando vamos criar uma variável e ficamos pensando como se dá a inicialização da mesma? Será que as variáveis sempre terão “lixo de memória” e precisarão ser inicializadas manualmente, ou o Delphi resolve isso pra gente? Bem, neste artigo a minha intenção é, justamente, clarear esses conceitos que tanto nos confundem. Vem comigo que eu vou te mostrar!
No Delphi temos, basicamente, dois conceitos que impactam diretamente na inicialização automática das variáveis, um é o escopo da variável e o outro está relacionado aos tipos de variáveis gerenciáveis.
Caso você não esteja familiarizado com um desses dois conceitos, sugiro a leitura de outro post aqui no blog intitulado “O que são as variáveis gerenciáveis do Delphi?”, pois nele eu falo brevemente sobre esses dois conceitos.
Escopo das variáveis
Em se tratando do escopo das variáveis, o primeiro ponto é em relação às variáveis globais. Neste caso, se não for definido um valor inicial para estas variáveis, o compilador irá inicializá-las automaticamente com “vazio”, isto é, para variáveis do tipo
string
as mesmas serão inicializadas com ''
, as variáveis do tipo Boolean
serão inicializadas com False
, as variáveis numéricas com 0
(zero) e as classes serão inicializadas com nil
.Para que consigamos ver essa inicialização, podemos criar um programa simples com algumas variáveis globais e colocá-las no Watch List. Por exemplo:
type TClasse = class FS: string; FI: Integer; FB: Boolean; end; TFoo = record S: string; I: Integer; B: Boolean; end; TFoo2 = record D: Double; I: Integer; B: Boolean; end; var _S: string; _I: Integer; _D: Double; _B: Boolean; _F: TFoo; _F2: TFoo2; _FC: TClasse; _ary: array[0..2] of Integer; _Dary: array of Integer;
Se executarmos a aplicação e, em algum ponto, colocarmos um breakpoint, conseguiremos ver pelo Watch List que as variáveis já foram inicializadas logo no início da aplicação.
E o mesmo acontecerá para as variáveis globais dentro de uma classe:
Já em relação às variáveis locais, estas terão seus valores indefinidos até que você defina um valor para elas. Este é um ponto onde precisamos tomar bastante cuidado, pois utilizar variáveis não inicializadas pode gerar erros ou resultados inesperados na execução do seu programa, já que seus valores, na maioria das vezes, estarão com o famoso lixo de memória. Veja o exemplo:
procedure TestandoVariaveisLocais(AValue: Boolean); var ary: array[0..2] of Integer; Dary: array of Integer; It: IInterfaceList; B: Boolean; S: string; I: Integer; D: Double; F: TFoo; F2: TFoo2; C: TClasse; begin // Um código qualquer aqui end;
Se executarmos a aplicação e, no início da
procedure
, colocarmos um breakpoint, conseguiremos ver pelo Watch List que as variáveis não foram inicializadas e estão com lixo de memória.Veja, aqui é importante dizer que muitas vezes o compilador pode usar um lixo de memória que nos engana a achar que as variáveis foram inicializadas corretamente, quando na verdade foi apenas uma coincidência elas “apontarem para o vazio”. Isso é simples de ver com a variável booleana. Se você observar, mesmo não tendo sido inicializada ela está como
True
o que nos dá a falsa impressão de que ela pode ter sido inicializada, mas acredite! Ela não foi!Agora, se você prestou atenção no meu print, deve estar se perguntando: Mas, e as variáveis
Dary
, e S
ou C
, elas também são um falso positivo?Não, neste caso, elas realmente foram inicializadas, e aqui entra o nosso segundo conceito, na qual comentei lá no início:
Variáveis gerenciáveis.
Como toda regra tem sua exceção, não poderia ser diferente aqui. Apesar de, por padrão, as variáveis locais não serem inicializadas pelo Delphi, a exceção se dará, justamente, no caso das variáveis com tipos gerenciáveis. Pois estes, sempre serão inicializados, mesmo se for uma variável local. É o caso, por exemplo, das
strings
, arrays dinâmicos
e interfaces
. Além dos records
que tiverem ao menos um campo gerenciável.Por fim, podemos concluir que:
- As variáveis globais sempre serão inicializadas pelo compilador;
- As variáveis locais nunca serão inicializadas pelo compilador, exceto que estas façam parte dos tipos gerenciáveis.
Autor: Flávia Melo
Postar um comentário