There is currently a kinda interesting discussion going on at the free
pascal mailing list which I was supposed to be de-described from... but it's
sending me messages anyway ;)
I decided to test "partial array initializations" to see if Delphi gives any
warning/hints messages.
Kinda surprising:
It gives none ?!
^ Could be a bad thing...
// *** Begin of Demonstration code ***
program TestProgram;
{$APPTYPE CONSOLE}
{
Testing partial array initialization.
version 0.01 created on 20 november 2009 by Skybuck Flying.
I decided to test this after an interesting posting on free pascal mailing
list...
No hints, no warnings...
Not good me thinks ! ;)
}
uses
SysUtils;
procedure ModifyArray( var ParaArray : array of byte );
begin
ParaArray[0] := 123; // notice rest of array is uninitialized, could lead
to bugs.
end;
procedure Test;
var
vTempArray : array[0..7] of byte;
begin
// even commenting this out doesn't trigger any warning/hint messages at
all... kinda odd ?!
// FillChar( vTempArray, 3, 0 ); // partial initialization
ModifyArray( vTempArray );
Writeln(vTempArray[0]);
end;
begin
try
Test;
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
ReadLn;
end.
// *** End of Demonstration code ***
Bye,
Skybuck.
[...]
> procedure ModifyArray( var ParaArray : array of byte );
> begin
> ParaArray[0] := 123; // notice rest of array is uninitialized,
> // could lead to bugs.
> end;
You're passing the array by reference. The entire array could be
reassigned as a whole, rather than just a single element.
The key word is 'could'. The compiler doesn't check, know, or care
if you actually do it, it just assumes after the ModifyArray call
that the passed array _was_ changed and therefore no longer qualifies
as uninitialised. Mind you, that's in the _calling_ code. The compiler
does not look into the called procedure. It can't tell in general
what code will actually be called (think 'virtual'); all it has to
work with is the procedure's signature.
You might prefer for the compiler to err on the side of caution...
for about five minutes. You'd end up with warnings you couldn't
meaningfully get rid of.
Groetjes,
Maarten Wiltink
Since when I created that example I noticed it did the same for just
variables... time to delve into that a bit more...
This could be a potential source of undetected bugs, take a look at this:
No hint/no warning what so ever !
// *** begin of example ***
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
procedure Test( var a : integer );
begin
// a := 123;
writeln('a: ', a);
end;
procedure Main;
var
b : integer;
begin
// no uninitialized variable warning ?!
Test( b );
writeln( 'b: ', b );
end;
begin
try
Main;
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
readln;
end.
// *** end of example ***
Bye,
Skybuck.