Sign in Join

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

Mailing lists / fpc-devel / 2019-01

Failure to recompile TAChart after FPC r40785 (committed by Jonas)

7 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

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

Werner Pamler

FPC trunk has not been very friendly to existing code recently...

Today with r40792, the TAChart package fails to recompile: "tadiagram.pas(347,38) Error: Only static methods and static variables can be referenced through an object type". The faulty code is

     operator = (const A, B: TDiaPosition): Boolean;
     begin
       Result := TDiaPosition.Equals(A, B);
     end;

where

   operator =(const A, B: TDiaPosition): Boolean; overload; inline;

and

   type
      TDiaPosition = object
      public
       class function Equals(const A, B: TDiaPosition): Boolean;       ...

The last revision with which this line compiles is r40784. The next one, r40785, committed yesterday by Jonas ("give an error when trying to call an object instance method via a type node"), introduces the new issue.

What can I do to revive the package?

Reply by email

Sven Barth
to Werner Pamler

Am Mo., 7. Jan. 2019, 15:55 hat Werner Pamler
geschrieben:

Show quoted text 29 lines
FPC trunk has not been very friendly to existing code recently... Today with r40792, the TAChart package fails to recompile: "tadiagram.pas(347,38) Error: Only static methods and static variables can be referenced through an object type". The faulty code is operator = (const A, B: TDiaPosition): Boolean; begin Result := TDiaPosition.Equals(A, B); end; where operator =(const A, B: TDiaPosition): Boolean; overload; inline; and type TDiaPosition = object public class function Equals(const A, B: TDiaPosition): Boolean; ... The last revision with which this line compiles is r40784. The next one, r40785, committed yesterday by Jonas ("give an error when trying to call an object instance method via a type node"), introduces the new issue. What can I do to revive the package?

Did you try to add "static" to the TDiaPosition.Equals class function? For an object type only instance and static class methods make sense so non static class methods should probably best be forbidden.

Regards,
Sven

Reply by email

Mattias Gaertner
to Sven Barth
Show quoted text 5 lines
[...] Did you try to add "static" to the TDiaPosition.Equals class function? For an object type only instance and static class methods make sense so non static class methods should probably best be forbidden.

True, reason is that *non* static means there is a Self. But since there is no "object of objecttype" and no "record of recordtype", there is no type for Self in class methods of objects/record.

Mattias

Reply by email

Jonas Maebe
to Mattias Gaertner: On Mon, 7 Jan 2019 17:13:21 +0100 True, reason is that *non* static means there is a Self.
Mattias Gaertner wrote
True, reason is that *non* static means there is a Self. But since there is no "object of objecttype" and no "record of recordtype", there is no type for Self in class methods of objects/record.

Object class methods do have a self parameter. If an object has a vmt, the object class methods get this vmt pointer passed as self parameter. Otherwise they get nil as self parameter. Kylix does not support calling object class methods through tobjecttype.classmethod either, which is indeed kind of strange.

It is not possible to declare a non-static class method (in FPC, at least; Kylix does not support "advanced records", so I cannot test there).

Jonas

Reply by email

Mattias Gaertner
to Jonas Maebe
Show quoted text 11 lines
On 07/01/19 17:32, Mattias Gaertner via fpc-devel wrote: > True, reason is that *non* static means there is a Self. > But since there is no "object of objecttype" and no "record of > recordtype", there is no type for Self in class methods of > objects/record. Object class methods do have a self parameter. If an object has a vmt, the object class methods get this vmt pointer passed as self parameter. Otherwise they get nil as self parameter. Kylix does not support calling object class methods through tobjecttype.classmethod either, which is indeed kind of strange.

Thanks. I learned something new.

But what is this Self?

  TBird = object
    class procedure DoIt; virtual;
  end;
class procedure TBird.DoIt;
var
  o: TBird;
begin
  o:=Self;
  // Error: Incompatible types: got "Class Of TBird" expected "TBird"
end;

But "Class Of TBird" does not exist in FPC, does it?

It is not possible to declare a non-static class method (in FPC, at least; Kylix does not support "advanced records", so I cannot test there).

Mattias

Reply by email

Jonas Maebe
to Mattias Gaertner
Mattias Gaertner wrote 26 lines
On Mon, 7 Jan 2019 19:24:53 +0100 Jonas Maebe wrote: > Object class methods do have a self parameter. If an object has a > vmt, the object class methods get this vmt pointer passed as self > parameter. Otherwise they get nil as self parameter. Kylix does not > support calling object class methods through tobjecttype.classmethod > either, which is indeed kind of strange. Thanks. I learned something new. But what is this Self? TBird = object class procedure DoIt; virtual; end; class procedure TBird.DoIt; var o: TBird; begin o:=Self; // Error: Incompatible types: got "Class Of TBird" expected "TBird" end; But "Class Of TBird" does not exist in FPC, does it?

No, it does not. The compiler currently unconditionally creates a classrefdef for the self parameter, regardless of whether it's a class or object type. This should probably changed into void pointer for objects. Although even Kylix prints "Error: Incompatible types: "TBird" and "Class Reference", so it seems we're also Delphi-compatible here :)

Jonas

Reply by email