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;
6
  • Is this really a dupe of that Q @TLama? Commented Nov 28, 2014 at 12:57
  • @David, it has an answer there. But well, e.g. this one is better. There will be more of them... [I'll reopen this one] Commented Nov 28, 2014 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. Commented Nov 28, 2014 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 ?". Commented Nov 28, 2014 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? Commented Sep 2, 2018 at 11:53

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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.
I don't know what to make of that comment. It's almost as though you don't believe me.
@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.)
@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.)
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.