4

Is something like this possible with Delphi? (with dynamic arrays of strings and records)

type
  TStringArray = array of String;
  TRecArray = array of TMyRecord;

procedure DoSomethingWithStrings(Strings : TStringArray);
procedure DoSomethingWithRecords(Records : TRecArray);
function BuildRecord(const Value : String) : TMyRecord;

DoSomethingWithStrings(['hello', 'world']);
DoSomethingWithRecords([BuildRecord('hello'), BuildRecord('world')]);

I know that it does not compile like that. Just wanted to ask if there's a trick to get something similar to that.

1
  • Be aware that writing procedure DoSomethingWithStrings(Strings : TStringArray); will create a temporary copy of the TStringArray parameter on the stack. You should better add a const here, i.e. write procedure DoSomethingWithStrings(const Strings : TStringArray); Commented Jun 7, 2011 at 13:06

1 Answer 1

6

If you don't have to change the length of the arrays inside your DoSomethingWith* routines, I suggest using open arrays instead of dynamic ones, e.g. like this:

procedure DoSomethingWithStrings(const Strings: array of string);
var
  i: Integer;
begin
  for i := Low(Strings) to High(Strings) do
    Writeln(Strings[i]);
end;

procedure DoSomethingWithRecords(const Records: array of TMyRecord);
var
  i: Integer;
begin
  for i := Low(Records) to High(Records) do
    Writeln(Records[i].s);
end;

procedure Test;
begin
  DoSomethingWithStrings(['hello', 'world']);
  DoSomethingWithRecords([BuildRecord('hello'), BuildRecord('world')]);
end;

Please note the array of string in the parameter list - not TStringArray! See the article "Open array parameters and array of const", especially the section about "Confusion", for more information.

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

5 Comments

+1 This is great. Thanks! I would have thought that array of String and TStringArray are type equivalent and therefore exchangeable but that does seem wrong.
That's one of Delphi's inconsistent areas. You can't write set of TMyEnum in a parameter list, you have to declare TMyEnums = set of TMyEnum and use that instead - same with pointers etc. But with arrays it's all different. :-)
The "incosistency" is just in the syntax because Delphi uses the same one with two different meaning based on context. "T: array of string" is a dynamic array. "procedure P(A: array of string)" is an open array parameter declaration - which is not a dynamic array, it takes any array of the given base type. If you want to pass explictly only dynamic arrays of a given type you would need a type declaration first and then a parameter of that type.
Probably "confusion" is the better expression: If you use Delphi some time you learn that P(AMyEnums: set of TMyEnum) doesn't work and that you'll have to declare a type explicitly. Now if you need to pass an array you will instinctively use an explicit type even if it's wrong.
IIRC that's because in Pascal two different var/param type declarations are not assignemnt compatible no matter how identical they are, thereby "A: array[0..1] of Bye; B: array[0..1] of Byte;" A and B are not assignment compatible, it works only if a type is declared first and then A and B declared of the same type. That's happens for parameters also. Open array parameters are a Delphi enhancement to Pascal rules, to allow for more flexibility in passing arrays to procedures, and IIRC they predates dynamic arrays

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.