6

I have a record type defined like:

type 
    TRecordType = record
        Field1: string;
        Field2: Variant;
    end;

And a function declaration using it:

function Function1(const Records: TArray<TRecordType>): TAnyOtherClass;

So far so good, but if the function is called like:

Function1([BuildRecord('string', value), BuildRecord('OtherString', otherValue)])

The compiler returns an error:

[DCC Error] AnyUnit.pas(142): E2001 Ordinal type required

I have read some place a long time ago that Delphi's compiler handles generics in a kind of preprocessor with string replacements done before really compiling the code, so I was expecting Function1 to become something like:

function Function1(const Records: array of TRecordType): TAnyOtherClass;

Because TArray is defined TArray<T> = array of T;.

I think it is not happening, because when I changed the function declaration to:

function Function1(const Records: array of TRecordType): TAnyOtherClass;

The code is compiled without errors or warnings.

There is an answer on [this question] 1 that links to an article explaining the difference, but the link there is broken.

So my question is, what means TArray<T> if not array of T?

2
  • 1
    Open arrays are not the same as a typed array. Open array parameters and array of const. Commented Sep 3, 2015 at 13:17
  • 1
    Delphi does not use a preprocessor for generics. Delphi generics are modelled on .Net generics. Commented Sep 3, 2015 at 13:37

1 Answer 1

5
Function1([BuildRecord('string', value), BuildRecord('OtherString', otherValue)])

The [...] syntax in your argument is what is known as an open array constructor. This documentation states, with my emphasis:

Open array constructors allow you to construct arrays directly within function and procedure calls. They can be passed only as open array parameters or variant open array parameters.

Your function accepts a (generic) dynamic array type, which is different from an open array. Your function is declared as

function Function1(const Records: TArray<TRecordType>): TAnyOtherClass;

The parameter is a (generic) dynamic array type. An open array parameter would look like this:

function Function1(const Records: array of TRecordType): TAnyOtherClass;

I know this looks very like the declaration of a dynamic array, but it is not. In Delphi, array of has two distinct meanings:

  • In the context of a parameter list, array of is used to declare an open array parameter.
  • Elsewhere, array of defines a dynamic array type.

This overloading of the language syntax is a common cause for confusion.

So, because of all this, the compiler rejects your code, because you are attempting to use an open array constructor with a parameter that is not an open array.

My answer here goes into this issue in more detail: https://stackoverflow.com/a/14383278/505088

I have read some place a long time ago that Delphi's compiler handles generics in a kind of preprocessor and some kind of string replace in code.

I think you are mis-remembering. What you are describing is more akin to C++ templates. Delphi generics are not handled by a preprocessor, not least because Delphi does not have a preprocessor.

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

6 Comments

So, it's a array's specific behavior, right? I am in doubt just on my declaration that the Delphi's compiler handles the generics on the preprocessor, this really proceeds?
@David, I think you need to explain the difference between: array of in type definition and in parameter lists. That seems to be the source of the confusing IMO. Right now you make a passing reference, but do not hit the issue on the head.
@jean It boils down to array of having two completely different meanings depending on the context. In a parmeter list, array of declares an open array parameter. Elsewhere, array of declares a type. Generics aren't really relevant here. The same issue would arise if you used a type that was a non-generic dynamic array, also defined with array of. Generics are not handled by the preprocessor, not least because Delphi does not have a preprocessor.
Thanks guys, i think i understand now.
@Jean, Please read this article on the subject: "Open array parameters and array of const". It will explain the difference between dynamic arrays and open array parameters.
|

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.