Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which variables are initialized when in Delphi?

So I always heard that class fields (heap based) were initialized, but stack based variables were not. I also heard that record members (also being stack based) were also not initialized. The compiler warns that local variables are not initialized ([DCC Warning] W1036 Variable 'x' might not have been initialized), but does not warn for record members. So I decided to run a test.

I always get 0 from Integers and false from Booleans for all record members.

I tried turning various compiler options (debugging, optimizations, etc.) on and off, but there was no difference. All my record members are being initialized.

What am I missing? I am on Delphi 2009 Update 2.

program TestInitialization;  {$APPTYPE CONSOLE}  uses   SysUtils;  type   TR = Record   Public     i1, i2, i3, i4, i5: Integer;     a: array[0..10] of Integer;     b1, b2, b3, b4, b5: Boolean;     s: String;   End;  var   r: TR;   x: Integer;  begin   try     WriteLn('Testing record. . . .');     WriteLn('i1 ',R.i1);     WriteLn('i2 ',R.i2);     WriteLn('i3 ',R.i3);     WriteLn('i4 ',R.i4);     WriteLn('i5 ',R.i5);      Writeln('S ',R.s);      Writeln('Booleans: ', R.b1, ' ', R.b2, ' ', R.b3, ' ', R.b4, ' ', R.b5);      Writeln('Array ');     for x := 0 to 10 do       Write(R.a[x], ' ');     WriteLn;      WriteLn('Done . . . .');   except     on E:Exception do       Writeln(E.Classname, ': ', E.Message);   end;   ReadLn; end. 

Output:

 Testing record. . . . i1 0 i2 0 i3 0 i4 0 i5 0 S Booleans: FALSE FALSE FALSE FALSE FALSE Array 0 0 0 0 0 0 0 0 0 0 0 Done . . . .  
like image 207
Jim McKeeth Avatar asked May 14 '09 00:05

Jim McKeeth


People also ask

How do you initialize a variable in Delphi?

Global variables can be initialized at the same time they are declared, using the syntax: var identifier: type = constantExpression; where constantExpression is any constant expression representing a value of type type.

Which variable should be initialized before use?

Local variables must be initialized before use, as they don't have a default value and the compiler won't let us use an uninitialized value.

What are initialized variables?

Initializing a variable means specifying an initial value to assign to it (i.e., before it is used at all). Notice that a variable that is not initialized does not have a defined value, hence it cannot be used until it is assigned such a value.


1 Answers

Global variables are zero-initialized. Variables used in the context of the main begin..end block of a program can be a special case; sometimes they are treated as local variables, particularly for-loop indexers. However, in your example, r is a global variable and allocated from the .bss section of the executable, which the Windows loader ensures is zero-filled.

Local variables are initialized as if they were passed to the Initialize routine. The Initialize routine uses runtime type-info (RTTI) to zero-out fields (recursively - if a field is of an array or record type) and arrays (recursively - if the element type is an array or a record) of a managed type, where a managed type is one of:

  • AnsiString
  • UnicodeString
  • WideString
  • an interface type (including method references)
  • dynamic array type
  • Variant

Allocations from the heap are not necessarily initialized; it depends on what mechanism was used to allocate memory. Allocations as part of instance object data are zero-filled by TObject.InitInstance. Allocations from AllocMem are zero-filled, while GetMem allocations are not zero-filled. Allocations from New are initialized as if they were passed to Initialize.

like image 63
Barry Kelly Avatar answered Sep 30 '22 14:09

Barry Kelly