Sign in Join

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

Mailing lists / fpc-pascal / 2023-05

Record Constructors which differ in parameter lists

6 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

Thomas Kurz

Hello,

let's take the following example:

program Project1;
{$MODE OBJFPC}
{$MODESWITCH ADVANCEDRECORDS}
{$MODESWITCH TYPEHELPERS}
type TVec3f = record
  x, y, z: Double;
  constructor Create (a1, a2, a3: Double);
end;
type TSomething = type TVec3f;
type TSomethingHelper = type helper for TSomething
  constructor Create (a1, a2: Double);
end;
constructor TVec3f.Create (a1, a2, a3: Double);
begin
  Self.x := a1;
  Self.y := a2;
  Self.z := a3;
end;
constructor TSomethingHelper.Create (a1, a2: Double);
begin
  Self.x := a1;
  Self.y := a2;
  Self.z := 1 - a1 - a2;
end;
var f: TVec3f;
begin
  f := TVec3f.Create (0.0, 0.0, 0.0);     // <-- error here
end.
I get the error:
project1.lpr(35,37) Error: Wrong number of parameters specified for call to "Create"
project1.lpr(25,30) Error: Found declaration: constructor Create(Double;Double);

So, obviously, FPC tries to apply the helper of TSomething (which should be decoupled from TVec3f because of the "type TVec3f" declaration) to TVec3f which hasn't defined any constructor with 2 parameters.

Is this intended behavior or should I report it as a bug?

Versions used:
Lazarus 2.3.0 (rev main-2_3-3525-g9208f17734) FPC 3.3.1 i386-win32-win32/win64 (FPC is not the most recent build, it's about 2~3 weeks old)

Michael Van Canneyt
to Thomas Kurz
Thomas Kurz wrote 49 lines
Hello, let's take the following example: program Project1; {$MODE OBJFPC} {$MODESWITCH ADVANCEDRECORDS} {$MODESWITCH TYPEHELPERS} type TVec3f = record x, y, z: Double; constructor Create (a1, a2, a3: Double); end; type TSomething = type TVec3f; type TSomethingHelper = type helper for TSomething constructor Create (a1, a2: Double); end; constructor TVec3f.Create (a1, a2, a3: Double); begin Self.x := a1; Self.y := a2; Self.z := a3; end; constructor TSomethingHelper.Create (a1, a2: Double); begin Self.x := a1; Self.y := a2; Self.z := 1 - a1 - a2; end; var f: TVec3f; begin f := TVec3f.Create (0.0, 0.0, 0.0); // <-- error here end. I get the error: project1.lpr(35,37) Error: Wrong number of parameters specified for call to "Create" project1.lpr(25,30) Error: Found declaration: constructor Create(Double;Double); So, obviously, FPC tries to apply the helper of TSomething (which should be decoupled from TVec3f because of the "type TVec3f" declaration) to TVec3f which hasn't defined any constructor with 2 parameters. Is this intended behavior or should I report it as a bug?

This is intended behaviour since declarations in helpers always take precedence over the methods in the class/record.

Try to add overload; to the constructor in the helper. This is a hint to the compiler that it should look for other methods.

Michael.

Thomas Kurz
to Michael Van Canneyt

Dear Michael,

thank you for the explanation. I understand that the helper overwrites the original constructor. But...

I have defined "type TSomething = type TVec3f" (note the second "type"). So from my perspective, I'd assume that the TSomethingHelper doesn't apply to TVec3f at all because TSomething is defined as a new type, not only an alias for TVec3f.

Earlier message 67 lines
----- Original Message ----- From: Michael Van Canneyt via fpc-pascal To: Thomas Kurz via fpc-pascal Sent: Tuesday, May 9, 2023, 23:55:47 Subject: [fpc-pascal] Record Constructors which differ in parameter lists On Tue, 9 May 2023, Thomas Kurz via fpc-pascal wrote: > Hello, > let's take the following example: > program Project1; > {$MODE OBJFPC} > {$MODESWITCH ADVANCEDRECORDS} > {$MODESWITCH TYPEHELPERS} > type TVec3f = record > x, y, z: Double; > constructor Create (a1, a2, a3: Double); > end; > type TSomething = type TVec3f; > type TSomethingHelper = type helper for TSomething > constructor Create (a1, a2: Double); > end; > constructor TVec3f.Create (a1, a2, a3: Double); > begin > Self.x := a1; > Self.y := a2; > Self.z := a3; > end; > constructor TSomethingHelper.Create (a1, a2: Double); > begin > Self.x := a1; > Self.y := a2; > Self.z := 1 - a1 - a2; > end; > var f: TVec3f; > begin > f := TVec3f.Create (0.0, 0.0, 0.0); // <-- error here > end. > I get the error: > project1.lpr(35,37) Error: Wrong number of parameters specified for call to "Create" > project1.lpr(25,30) Error: Found declaration: constructor Create(Double;Double); > So, obviously, FPC tries to apply the helper of TSomething (which should be decoupled from TVec3f because of the "type TVec3f" declaration) to TVec3f which hasn't defined any constructor with 2 parameters. > Is this intended behavior or should I report it as a bug? This is intended behaviour since declarations in helpers always take precedence over the methods in the class/record. Try to add overload; to the constructor in the helper. This is a hint to the compiler that it should look for other methods. Michael.
Michael Van Canneyt
to Thomas Kurz
Thomas Kurz wrote 8 lines
Dear Michael, thank you for the explanation. I understand that the helper overwrites the original constructor. But... I have defined "type TSomething = type TVec3f" (note the second "type"). So from my perspective, I'd assume that the TSomethingHelper doesn't apply to TVec3f at all because TSomething is defined as a new type, not only an alias for TVec3f.

I would expect the type helper to remain functional. The types are the same for all purposes except they have a different RTTI entry.

But the exact behaviour of the compiler in this case is something that Sven Barth will need to explain...

Michael.

Thomas Kurz
to Michael Van Canneyt
I would expect the type helper to remain functional. The types are the same for all purposes except they have a different RTTI entry.

But this behaviour seems inconsistent to me. For example:

With "var x:double" I can use "x.IsNan". With TDateTime, which is defined as "type TDateTime = type Double", I cannot.

With strings, I can use "x.IsEmpty". With Utf8String, which is defined as "type TUtf8String = type AnsiString", I cannot.

Michael Van Canneyt
to Thomas Kurz
Thomas Kurz wrote 8 lines
> I would expect the type helper to remain functional. The types are the same > for all purposes except they have a different RTTI entry. But this behaviour seems inconsistent to me. For example: With "var x:double" I can use "x.IsNan". With TDateTime, which is defined as "type TDateTime = type Double", I cannot. With strings, I can use "x.IsEmpty". With Utf8String, which is defined as "type TUtf8String = type AnsiString", I cannot.

It's not because I expect it to, that it is actually so.

As I said, Sven will need to explain what the current behaviour actually is...

Michael.