0

During a review process of an older programm code the following question arised: All local variables in a method are initialized right after begin. Usually local variables are not initialized. But we have a procedure where all variables are initialized to 0. Does anybody has an idea how this could happen?

Example:

type
  TPrices = array[0..10, 0..5] of Integer;

procedure DoSomething();
var
  mPrices : TPrices;
  mValue  : Integer; 
begin
  if (mPrices[0,0] = 0) then
    MessageDlg('Zero', mtInformation, [mbOK], 0);
  if (mValue = 0) then
    MessageDlg('Zero Integer', mtInformation, [mbOK], 0);
end;
elite
  • 191
  • 2
  • 13
  • Is this really a dupe of that Q @TLama? – David Heffernan Nov 28 '14 at 12:57
  • @David, it has an answer there. But well, e.g. [`this one`](http://stackoverflow.com/q/861045/960757) is better. There will be more of them... [I'll reopen this one] – TLama Nov 28 '14 at 13:03
  • @TLama That "this one" question doesn't relate to local variables in a method/procedure, but about global variables. I quite like the one used for the duplicate better. – Lasse V. Karlsen Nov 28 '14 at 13:04
  • @Lasse, yes, but if we were pedantic, we could follow the title up to the duplicate question link saying *"This question already has an answer here"*. Both questions have answer to this one. And I would personally link a question asking for *"How is a local variable of an unmanaged type initialized ?"* with a question asking for *"How are variables initialized in general ?"*. – TLama Nov 28 '14 at 13:12
  • @DavidHeffernan: While I do agree that having everything in a single, top-down reply is nice -- there is also something to be said about short, to the point answers. With all the string changes that have taken place I googled to double check the state of 10.2 since I am porting a legacy project from D2006 (with the TMS unicode hell). I had to click 8 times before I found answer 861045, and then this one. I can only imagine what a complete novice experience this. Perhaps allow a few straight answers to pass and then comment in a reference to a major reply? – Jon Lennart Aasenden Sep 02 '18 at 11:53
  • @DavidHeffernan Note: The reason I mention "clicks" is due to the notion of 3 clicks being optimal for design and documentation. While I dont remember the author's name there was a good book on this, where good information-flow should be optimized for category, topic and subject. A bit anal perhaps but still a natural organizational pattern in both through and nature. – Jon Lennart Aasenden Sep 02 '18 at 11:56

1 Answers1

7

This is just down to chance. The variable is not initialized. The variable will reside on the stack, and if it so happens that whatever was last written to that location of the stack was zero, then the value there will still be zero.

Local variables of unmanaged types are not initialized. Do not allow coincidences like the above persuade you otherwise.

Consider this program:

{$APPTYPE CONSOLE}

type
  TPrices = array[0..10, 0..5] of Integer;

procedure Foo;
var
  mPrices: TPrices;
begin
  Writeln(mPrices[0,0]);
end;

begin
  Foo;
end.

When I run on my machine, the output is:

1638012

Now consider this program:

{$APPTYPE CONSOLE}

type
  TPrices = array[0..10, 0..5] of Integer;

procedure Foo;
var
  mPrices: TPrices;
begin
  Writeln(mPrices[0,0]);
  FillChar(mPrices, SizeOf(mPrices), 0);
end;

procedure Bar;
var
  mPrices: TPrices;
begin
  Writeln(mPrices[0,0]);
end;

begin
  Foo;
  Bar;
end.

This time the output is:

1638012
0

It so happens that the two functions place their local variables in the same location and the fact that the first function call zeroed the local variable before returning affects the uninitialized value of the other local variable in the second function.

Or try this program:

{$APPTYPE CONSOLE}

type
  TPrices = array[0..10, 0..5] of Integer;

procedure Foo;
var
  mPrices: TPrices;
begin
  Writeln(mPrices[0,0]);
  FillChar(mPrices, SizeOf(mPrices), 0);
  mPrices[0,0] := 666;
end;

procedure Bar;
var
  mPrices: TPrices;
begin
  Writeln(mPrices[0,0]);
  Writeln(mPrices[0,1]);
end;

begin
  Foo;
  Bar;
end.

Now the output is:

1638012
666
0

As you might imagine, many different things could lead to the content of that stack space changing. So trust what you know. Local variables of unmanaged types are not initialized.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I also exptected to get different initialization values, but when I add a realy big array (2000x100), all the values of the array are initialized to zero too. Very unrealistic for uninitialized variable. Additionaly I added a method directly infront of calling the above method where I initialized an array (size 100x100) with $FF. And once more: everything in the above method has been 0. – elite Nov 28 '14 at 13:09
  • I don't know what to make of that comment. It's almost as though you don't believe me. – David Heffernan Nov 28 '14 at 13:12
  • @elite What's unrealistic? Is it really unrelaistic that when your machine is off, there's no current in the RAM. So when you switch it on, most of your RAm happens to be in a default state of all zeroes? Is it unrealistic that before your program started running something happened to clear a block of memory where your callstack is now allocated? (The OS might initialise the call stack before starting your app. But this will happen **only once** - which is why you cannot rely on it. And if the OS does happen to initialise the callstack - that could change.) – Disillusioned Nov 28 '14 at 15:15
  • @elite If you want to provide a simple example demonstrating your test of initialising arrays with $FF not working as expected, we can explain what you did wrong. (I would guess that you might have used a dynamic array.) – Disillusioned Nov 28 '14 at 15:18
  • 1
    After some more testing, I came to the conclusion that the behaviour here seems to be a chain of possibilities that in my case allways lead to a memory with zeroes. Maybe it has something to do with the amount of memory, needed in the function, but I don't know exactly. Thanks for your patience. – elite Dec 01 '14 at 08:43