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)

Reply by email

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.

Reply by email

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.

Reply by email

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.

Reply by email

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.

Reply by email

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.

Reply by email