Saturday, September 10, 2011

Hard-to-find lack of variable initialization issue

Another bug which I once encountered, raised from using local (i.e., stack) method (or procedure/function) variables of record type. When you forget to assign some value to simple local variable, and then try to use it, Delphi compiler warns about it:
Variable "VarName" might not have been initialized
But when you have record-type local variable, and somewhere passes it as a parameter to another function, the Delphi (7) compiler does not check that you have initialized all fields. It will silently use whatever values was in memory at the call stack on the location that was taken for such record field. So you must be especially careful when using local record vars. Doing ZeroMemory on all such records at the very beginning of the function (or procedure/method), seems to be a good habit, otherwise it is a big chance that you will lose some valuable time trying to understand why the program behaves so strange.

To illustrate what has been said, take a look at the following code:

type
  TFoo = record
    a, b: Integer;
  end;

procedure A(Foo: TFoo);
begin
end;

procedure B;
var
  Foo: TFoo;
begin
  A(Foo);
end;

Compiler will not say anything on A(Foo) source code string.
The following string
ZeroMemory(@Foo, SizeOf(Foo));
before A(Foo), if will not make your program free of logical errors, but at least will make the program behavior predictable and reproducible.

No comments:

Post a Comment