Sunday, April 29, 2007

Passing array of items in Delphi.Net - revisit

I have blogged about the worrying result of passing array of items in Delphi.Net using the "array of" type.

Apparently, there is another way to specify array of items to a function, that generates the same parameter type in IL code but causing the compiler to generate slightly different code inside the function, all without warning the user.

The technique is akin to C/C++'s use of typedef, except that in C/C++, typedef does not cause the compiler to generate different code. It is merely a form of short hand notation.

Not so in Delphi.Net.

The different form of specifying the array of items in a function's argument is by means of a type alias like this:

type
TArraryOfString = array of String;

procedure TSample.DoSomething(ar: TArrayOfString);
begin
// ....
end;

This form of declaration instructs the compiler not to overwrite the ar argument with its cloned copy. If one examine the IL code for the method's signature, it is identical to that of using "array of String" syntax. This generates identical code to that using any non-Delphi.Net languages.

This is a dangerous practice because both Delphi.Net Pascal syntax generate the same method signature in IL but with very different code in the function body and the developer is not told of the difference. The developer cannot see and feel any difference. The only time a developer can feel anything is different is when one tried to pass a nil array to the function. It is even worse if that assembly is to be used with other .Net assembly which can result in difference in behaviour, see my previous blog.

The morale of the story: Do not trust any assembly that is developed in Delphi.Net with array of parameter. Always check the code, with the help of Lutz Reflector or ILDasm, to determine if the argument has been overwritten with its clone. No non-Delphi.Net language will generate code like that without explicit action from the developer.

You can test this by passing a nil in the argument where you see array of in a method. If you get an NullReferenceException on entry to the method before your source code, you can bet your dollar that if is a Delphi.Net assembly using "array of" parameter.

Borland is more interested in Delphi.Win32 compatibility than to produce a compiler that generate safe, well behave and ECMA conforming assemblies.

No comments:

Post a Comment