Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2011-08

Using "array of xxx" in function call, Delphi compatibility

8 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Juha Manninen

Hi

While reading a bug report I made the following experiment with Delphi 2009 and then with Lazarus + FPC 2.4.4.

TMainMenu.Items is of type TMenuItem. TMenuItem has only one version of "Add" method and it takes another TMenuItem as parameter (checked from VCL source).
Still, to my surprise, the code works in Delphi.

FPC says: Error: Incompatible type for arg no. 1: Got "Dynamic Array Of TMenuItem", expected "TMenuItem"
which is what I expected also from Delphi.

---
procedure TForm1.FormCreate(Sender: TObject);
var
  ma: array of TMenuItem;
  mi: TMenuItem;
begin
  SetLength(ma, 2);
  mi := TMenuItem.Create(MainMenu1);
  mi.Caption := 'File';
  ma[0] := mi;
  mi := TMenuItem.Create(MainMenu1);
  mi.Caption := 'Help';
  ma[1] := mi;
  MainMenu1.Items.add(ma); // Works in Delphi
end;
---

Is this a known issue?

Regards
Juha

Reply by email

Jonas Maebe
to Juha Manninen
Juha Manninen wrote 8 lines
TMainMenu.Items is of type TMenuItem. TMenuItem has only one version of "Add" method and it takes another TMenuItem as parameter (checked from VCL source). Still, to my surprise, the code works in Delphi. FPC says: Error: Incompatible type for arg no. 1: Got "Dynamic Array Of TMenuItem", expected "TMenuItem" which is what I expected also from Delphi.

It is always best to isolate such things in a self-contained example that does not depend on external code. Does this compile with your Delphi version?

***
type
  tc = class
  end;
procedure add(c: tc);
begin
end;
var
  a: array of tc;
begin
  add(a);
end.
***

If not, the issue is something else. It seems more likely to me that there is somewhere another "add" method that Delphi picks up but FPC doesn't. E.g., there is at least also "TComponent.Add(item : IUnknown) : Integer;". While that one won't accept a dynamic array, maybe Delphi 2009 has more add methods in TComponent declared with "overload" (although normally searching for overloads should stop as soon as a method is found in a class without "overload", so in principle the search should stop when tmenuitem.add is encountered).

If the above does compile, what does it actually do? Pass the first element of the array?

Jonas

Reply by email

Ludo Brands
to Jonas Maebe
Show quoted text 45 lines
> TMainMenu.Items is of type TMenuItem. TMenuItem has only one version > of "Add" method and it takes another TMenuItem as parameter (checked > from VCL source). Still, to my surprise, the code works in Delphi. > > FPC says: Error: Incompatible type for arg no. 1: Got "Dynamic Array > Of TMenuItem", expected "TMenuItem" which is what I expected also from > Delphi. It is always best to isolate such things in a self-contained example that does not depend on external code. Does this compile with your Delphi version? *** type tc = class end; procedure add(c: tc); begin end; var a: array of tc; begin add(a); end. *** If not, the issue is something else. It seems more likely to me that there is somewhere another "add" method that Delphi picks up but FPC doesn't. E.g., there is at least also "TComponent.Add(item : IUnknown) : Integer;". While that one won't accept a dynamic array, maybe Delphi 2009 has more add methods in TComponent declared with "overload" (although normally searching for overloads should stop as soon as a method is found in a class without "overload", so in principle the search should stop when tmenuitem.add is encountered). If the above does compile, what does it actually do? Pass the first element of the array?

Delphi has a procedure TMenuItem.Add(const AItems: array of TMenuItem); overload; which isn't implemented in Lazarus. It existed already in Delphi6. So, not a compiler issue.

Ludo

Reply by email

Juha Manninen
to Jonas Maebe: It is always best to isolate such things in a self-contained example that does not depend…

2011/8/13 Jonas Maebe

It is always best to isolate such things in a self-contained example that does not depend on external code. Does this compile with your Delphi version?

Yes, I should have done that. The code you gave does not compile.

If not, the issue is something else. It seems more likely to me that there

Show quoted text 11 lines
is somewhere another "add" method that Delphi picks up but FPC doesn't. E.g., there is at least also "TComponent.Add(item : IUnknown) : Integer;". While that one won't accept a dynamic array, maybe Delphi 2009 has more add methods in TComponent declared with "overload" (although normally searching for overloads should stop as soon as a method is found in a class without "overload", so in principle the search should stop when tmenuitem.add is encountered). If the above does compile, what does it actually do? Pass the first element of the array?

The original code which works in Delphi is interesting because it not only compiles but it also works perfectly, adding those 2 menuitems to mainmenu.

There is no TComponent.Add, neither in VCL nor LCL. I try to figure out what is happening...

Thanks for replying.

Juha

Reply by email

Sven Barth
to Jonas Maebe: It is always best to isolate such things in a self-contained example that does not depend…
Jonas Maebe wrote 33 lines
On 13 Aug 2011, at 12:28, Juha Manninen wrote: > TMainMenu.Items is of type TMenuItem. TMenuItem has only one version of > "Add" method and it takes another TMenuItem as parameter (checked from VCL > source). > Still, to my surprise, the code works in Delphi. > > FPC says: Error: Incompatible type for arg no. 1: Got "Dynamic Array Of > TMenuItem", expected "TMenuItem" > which is what I expected also from Delphi. It is always best to isolate such things in a self-contained example that does not depend on external code. Does this compile with your Delphi version? *** type tc = class end; procedure add(c: tc); begin end; var a: array of tc; begin add(a); end. *** If not, the issue is something else. It seems more likely to me that there is somewhere another "add" method that Delphi picks up but FPC doesn't. E.g., there is at least also "TComponent.Add(item : IUnknown) : Integer;". While that one won't accept a dynamic array, maybe Delphi 2009 has more add methods in TComponent declared with "overload" (although normally searching for overloads should stop as soon as a method is found in a class without "overload", so in principle the search should stop when tmenuitem.add is encountered). If the above does compile, what does it actually do? Pass the first element of the array?

Related question, but the other way round. The following code does compile in FPC (didn't test Delphi). Is that by design?

=== source begin ===

procedure Test(a: array of String);
var
   s: String;
begin
   for s in a do
     Writeln(s);
end;
procedure Test2(a: array of Integer);
var
   i: Integer;
begin
   for i in a do
     Writeln(i);
end;
var
   s: String;
   i: Integer;
begin
   s := 'Hello World';
   Test(s);
   i := 42;
   Test2(i);
end.

=== source end ===

Calling "Test" with a constant string ("Test('Hello World');") or "Test2" with a constant integer ("Test2(42);") does not compile though...

Regards,
Sven

Reply by email

Jonas Maebe
to Sven Barth
Sven Barth wrote
Related question, but the other way round. The following code does compile in FPC (didn't test Delphi). Is that by design?

[snip passing single element to open array parameter]

Yes. It also works in TP/Delphi.

Jonas

Reply by email

Sven Barth
to Jonas Maebe
Jonas Maebe wrote 7 lines
On 13 Aug 2011, at 18:17, Sven Barth wrote: > Related question, but the other way round. The following code does compile in FPC (didn't test Delphi). Is that by design? [snip passing single element to open array parameter] Yes. It also works in TP/Delphi.

Ok, thanks. I just stumbled upon it some time ago by accident (like the TVarRec cast some more time ago ^^)

Regards,
Sven

Reply by email