Interface bug or some new feature

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Interface bug or some new feature

denisgolovan
Hi all

I've been using 3.1.1 compiler for a long time and now I am trying to upgrade to 3.3.1 from trunk.
However, I am stuck with some new behavior when using classes + interfaces.
I've managed to reproduce it in a small example which follows.

Specifically 3.1.1 compiler compiles it and correctly prints "Double".
3.3.1 compiler refuses to compile it at all.
Please comment if it's a bug or a new breaking feature.

//==================================================================
program project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes
  { you can add units after this };

type
  IIntf1 = interface
    procedure P(i:Integer);
  end;

  TClass1 = class(TInterfacedObject, IIntf1)
    procedure P(i:Integer);
  end;

  IIntf2 = interface(IIntf1)
    procedure P(f:Double);
  end;

  TClass2 = class(TClass1, IIntf2) // Error: No matching implementation for interface method "P(LongInt);" found
    procedure P(f:Double);
  end;

procedure TClass1.P(i:Integer);
begin
  WriteLn('Integer');
end;

procedure TClass2.P(f:Double);
begin
  WriteLn('Double');
end;

var v2:TClass2;
begin
  v2:=TClass2.Create;
  v2.P(0.0);
  v2.Free;
end.
//===================================================================


--
Regards,
Denis Golovan
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Interface bug or some new feature

Jonas Maebe-3
On 06/01/19 11:42, denisgolovan wrote:

> Specifically 3.1.1 compiler compiles it and correctly prints "Double".
> 3.3.1 compiler refuses to compile it at all.
> Please comment if it's a bug or a new breaking feature.

http://wiki.freepascal.org/User_Changes_Trunk#Methods_implementing_interface_methods_and_overloads


Jonas
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Interface bug or some new feature

Free Pascal - General mailing list
In reply to this post by denisgolovan
Am So., 6. Jan. 2019, 11:42 hat denisgolovan <[hidden email]> geschrieben:
Hi all

I've been using 3.1.1 compiler for a long time and now I am trying to upgrade to 3.3.1 from trunk.
However, I am stuck with some new behavior when using classes + interfaces.
I've managed to reproduce it in a small example which follows.

Specifically 3.1.1 compiler compiles it and correctly prints "Double".
3.3.1 compiler refuses to compile it at all.
Please comment if it's a bug or a new breaking feature.

//==================================================================
program project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes
  { you can add units after this };

type
  IIntf1 = interface
    procedure P(i:Integer);
  end;

  TClass1 = class(TInterfacedObject, IIntf1)
    procedure P(i:Integer);
  end;

  IIntf2 = interface(IIntf1)
    procedure P(f:Double);
  end;

  TClass2 = class(TClass1, IIntf2) // Error: No matching implementation for interface method "P(LongInt);" found
    procedure P(f:Double);
  end;

procedure TClass1.P(i:Integer);
begin
  WriteLn('Integer');
end;

procedure TClass2.P(f:Double);
begin
  WriteLn('Double');
end;

var v2:TClass2;
begin
  v2:=TClass2.Create;
  v2.P(0.0);
  v2.Free;
end.

The default visibility for classes without $M+ is private. Thus TClass1.P is private. An interface implementation does not have access to private methods of a parent class. So you need to declare P as protected for this to work. 
Though to be fair in the specific example you gave I think that it should work as both are within the same unit. We'll need to check that... 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Interface bug or some new feature

denisgolovan
In reply to this post by Jonas Maebe-3


06.01.2019, 14:57, "Jonas Maebe" <[hidden email]>:
> http://wiki.freepascal.org/User_Changes_Trunk#Methods_implementing_interface_methods_and_overloads
>
> Jonas

Thanks, Jonas.
That was precisely the cause for my trouble.

--
Regards,
Denis Golovan

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Interface bug or some new feature

denisgolovan
In reply to this post by Free Pascal - General mailing list
 
 
06.01.2019, 15:00, "Sven Barth via fpc-pascal" <[hidden email]>:
 
The default visibility for classes without $M+ is private. Thus TClass1.P is private. An interface implementation does not have access to private methods of a parent class. So you need to declare P as protected for this to work. 
Though to be fair in the specific example you gave I think that it should work as both are within the same unit. We'll need to check that... 
 
Yes. That was another real issue in my project.
However I managed to get it.
Thanks for quick help.
 
-- 
Regards,
Denis Golovan
 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Interface bug or some new feature

Free Pascal - General mailing list
Am 06.01.2019 um 13:30 schrieb denisgolovan:

> 06.01.2019, 15:00, "Sven Barth via fpc-pascal"
> <[hidden email]>:
>> The default visibility for classes without $M+ is private. Thus
>> TClass1.P is private. An interface implementation does not have
>> access to private methods of a parent class. So you need to declare P
>> as protected for this to work.
>> Though to be fair in the specific example you gave I think that it
>> should work as both are within the same unit. We'll need to check
>> that...
> Yes. That was another real issue in my project.
> However I managed to get it.
> Thanks for quick help.
Slight correction: the default visibility is Public, not Private, so
that shouldn't have been the problem with the specific example. :/

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Interface bug or some new feature

Free Pascal - General mailing list
In reply to this post by Jonas Maebe-3
Am 06.01.2019 um 12:56 schrieb Jonas Maebe:
> On 06/01/19 11:42, denisgolovan wrote:
>
>> Specifically 3.1.1 compiler compiles it and correctly prints "Double".
>> 3.3.1 compiler refuses to compile it at all.
>> Please comment if it's a bug or a new breaking feature.
>
> http://wiki.freepascal.org/User_Changes_Trunk#Methods_implementing_interface_methods_and_overloads 
>

But shouldn't that specifc example work? TClass1.P is public here, not
private.

Also unlike FPC Delphi does not give the following warning: Warning: An
inherited method is hidden by "P(Double);"

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Interface bug or some new feature

Jonas Maebe-3
On 06/01/19 14:00, Sven Barth via fpc-pascal wrote:

> Am 06.01.2019 um 12:56 schrieb Jonas Maebe:
>> On 06/01/19 11:42, denisgolovan wrote:
>>
>>> Specifically 3.1.1 compiler compiles it and correctly prints "Double".
>>> 3.3.1 compiler refuses to compile it at all.
>>> Please comment if it's a bug or a new breaking feature.
>>
>> http://wiki.freepascal.org/User_Changes_Trunk#Methods_implementing_interface_methods_and_overloads 
>>
>
> But shouldn't that specifc example work? TClass1.P is public here, not
> private.

It's unrelated to public and private (that is covered in
http://wiki.freepascal.org/User_Changes_Trunk#Visibility_of_methods_implementing_interface_methods 
). It's only about overloads. If you do not declare a method as
"overload", the compiler will now stop searching the class hierarchy as
soon as it finds a class that declares a method with the right name. It
already did this when calling methods, now it also does it for interface
method resolution.

> Also unlike FPC Delphi does not give the following warning: Warning: An
> inherited method is hidden by "P(Double);"

At least Kylix fails to compile the test program:

Borland Delphi for Linux Version 14.5
Copyright (c) 1983,2002 Borland Software Corporation
tt.pp(31) Error: Declaration of 'P' differs from declaration in
interface 'IIntf2'
tt.pp(49)


Jonas
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal