Why can I pass a var of type X to a open array parameter of that type?
Asked Answered
P

1

9

Using Delphi XE-2 (all updates applied).

I would expect the following code to generate compilation errors on the DoSomething and DoInteger calls, but it doesn't.

program OpenArrayQuestion;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

type
  IComposite = interface(IInterface)
  ['{1AC3CF6A-1316-4838-B67B-9FB075585C1E}']
  end;

  IComposite<T: IComposite> = interface(IComposite)
  ['{7F866990-9973-4F8E-9C1F-EF93EF86E8F2}']
  end;

function DoSomething(const aData: array of IComposite): Boolean;
begin
  Result := True;
end;

function DoInteger(const aData: array of Integer): boolean;
begin
  Result := True;
end;

var
  FData: IComposite;
  FInteger: Integer;
begin
  DoSomething(FData);
  DoInteger(FInteger);
end.

Can somebody explain why I can pass FData/FInteger - both just single variables, to an open array parameter of their respective types without putting it between []'s and without the compiler barfing it right back at me?

I thought it might have to do with an array of interfaces, or even the generics involved, but the compiler accepts an integer passed to an open array of integer as well.

Pepsin answered 21/11, 2012 at 9:43 Comment(0)
B
7

The compiler is being a little lax because there is no ambiguity in doing so.

Consider the following:

program OpenArrays;

{$APPTYPE CONSOLE}

procedure Test1(i: Integer); overload;
begin
  Writeln('Test1Integer');
end;

procedure Test1(i: array of Integer); overload;
begin
  Writeln('Test1OpenArray');
end;

procedure Test2(i: array of Integer);
begin
  Writeln('Test2');
end;

var
  i: Integer;

begin
  Test1(i);
  Test1([i]);
  Test2(i);
  Readln;
end.

which produces this output:

Test1Integer
Test1OpenArray
Test2

I've overloaded Test1 so that there is a version that receives an integer, and a version that receives an open array of integers. In that situation, the call Test1(i) goes to the overload that receives just an integer. On the other hand, I can call Test2 which receives an open array, just by passing an integer.


I believe that this behaviour is not documented in the language guide. However, @hvd found the following in the documentation for compiler error E2192 (emphasis mine):

Open array arguments must be supplied with an actual array variable, a constructed array or a single variable of the argument's element type.

Barbados answered 21/11, 2012 at 9:58 Comment(5)
It's in the documentation for error E2192: "Open array arguments must be supplied with an actual array variable, a constructed array or a single variable of the argument's element type." I don't see it in the documentation where I expected to find it, though.Valentinavalentine
Well, I'll be darned... Thanks David. And thanks @hvd for digging up that error documentation. Not exactly where you would expect to find such information.Pepsin
@hvd Well played indeed. I'd love to know, how on earth did you find that?Barbados
@DavidHeffernan I searched for "open array" (not in the index, in the search window) in the help, that one was the second result.Valentinavalentine
@hvd Very good. I tend not to use the help since it takes an eternity to start and I have no patience! I prefer the online version which seems quicker! Had I done that I would have found that topic too. Whether or not I would have actually looked at the documentation for an error message I doubt. Thanks for alerting me to the possibility that useful nuggets of info can be found inside compiler error documentation.Barbados

© 2022 - 2024 — McMap. All rights reserved.