Recent

Author Topic: Should this be a bug in Free Pascal?  (Read 1751 times)

EganSolo

  • Sr. Member
  • ****
  • Posts: 290
Should this be a bug in Free Pascal?
« on: February 20, 2020, 12:19:13 am »
Maybe I'm a purist when it comes to the language, but I've encountered this feature, which is cool and annoying at the same time. Consider this code:
Code: Pascal  [Select][+][-]
  1. Program Project1;
  2.  
  3. Program Project1;
  4.  
  5. Type
  6.  
  7.   { Class1 }
  8.  
  9.   Class1 = class
  10.   private
  11.     fName : String;
  12.   public
  13.    function Clone: Class1; virtual;
  14.    property Name : String read fName write fName;
  15.   End;
  16.  
  17.  
  18.   { Class2 }
  19.  
  20.   Class2 = class(Class1)
  21.   public
  22.    function Clone: Class2; override;
  23.   End;
  24.  
  25. { Class1 }
  26.  
  27. Function Class1.Clone: Class1;
  28. Begin
  29.   Result := Class1.Create;
  30.   Result.Name := fName;
  31. End;
  32.  
  33. { Class2 }
  34.  
  35. Function Class2.Clone: Class2;
  36. Begin
  37.   Result      := Class2.Create;
  38.   Result.Name := fName;
  39. End;
  40.  
  41. Var C1       : Class1;
  42.     C2a, C2b : Class2;
  43. Begin
  44.   C2a := Class2.Create;
  45.   C2a.Name := 'Class 2';
  46.   C1 := C2a;
  47.   //Next code line -- compilation error:
  48.   //Incompatible types: got "Class1" expected "Class2"
  49.   C2b := C1.Clone;
  50. End.
  51.  
  52.  

Nothing fancy here, but look at the signature of the overridden method Clone. The initial method returns Class1, the overridden method returnsClass2. Shouldn't the compiler flag it as an error? In fact it complains (rightly so) when I assign the return of this function from an instance of Class1 to an instance of Class2, as indicated by the comment in the code.

Thoughts?

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: Should this be a bug in Free Pascal?
« Reply #1 on: February 20, 2020, 03:44:55 am »
I am not totally following your code but I noticed you never called the inherited Clone from the Class2.. So this means clone 1 never gets executed. etc..

 I think if you were to do such things you'll have even a greater error..
The only true wisdom is knowing you know nothing

egsuh

  • Hero Member
  • *****
  • Posts: 1273
Re: Should this be a bug in Free Pascal?
« Reply #2 on: February 20, 2020, 04:52:59 am »
Are you saying that compiler should have issued error message at the declaration stage? I don't know, but if this is not an error then it is a very big discovery for me.

The error at the last sentence is very natural because inheritance means allowing parent := child; relationship but not vice versa.

What about C1 := C2a.Clone ?

EganSolo

  • Sr. Member
  • ****
  • Posts: 290
Re: Should this be a bug in Free Pascal?
« Reply #3 on: February 20, 2020, 07:08:03 am »
@egush: Yes, I am saying that the compiler ought to flag it as an error since the full function signature is different.
@Jamie: But I am calling it. The variable C1 is assigned C2 and then C1.prove is invoked which means that C2.probe is invoked.



Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: Should this be a bug in Free Pascal?
« Reply #4 on: February 20, 2020, 09:52:28 am »
  C2b := C1.Clone as Class2;

The compiler is unable to resolve what you mean otherwise. (Hardcast is also possible, but this is a bit safer)
Specialize a type, not a var.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: Should this be a bug in Free Pascal?
« Reply #5 on: February 20, 2020, 10:12:09 am »
In principle this is called type coercion and for example C++ supports it. Right now I can't tell whether FPC supports this on purpose or by accident (I'd need to check that).

But even if FPC supports it on purpose you'll have to cast the result of Clone if it's called on a TClass1 type as the compiler can not know that it's a type that has declared Clone with another subtype as result (okay, in this specific case in theory it could, but this doesn't apply to the general case and also this would contradict the language rules).

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Should this be a bug in Free Pascal?
« Reply #6 on: February 20, 2020, 10:21:28 am »
In principle this is called type coercion and for example C++ supports it. Right now I can't tell whether FPC supports this on purpose or by accident (I'd need to check that).

I think I proposed it once, only to find out it already existed. So I think it is deliberate.

EganSolo

  • Sr. Member
  • ****
  • Posts: 290
Re: Should this be a bug in Free Pascal?
« Reply #7 on: February 21, 2020, 05:15:13 am »
@Thaddy: Correct but that's not the point. Should we be able to declare an override of a function that returns a different type? That's what I'm trying to understand. In this instance, if I were to call C2.Clone, I'd get back a class of type C2 (with no casting) whereas if I called C1.Clone, I'd get back a class of type C1.

I thought that overriding retained the full signature as-is with no change but it looks like Free Pascal is more flexible.  @marcov and @PascalDragon seem to imply that it's by design, which is great and therefore the declaration is no bug and could be fully utilized.

egsuh

  • Hero Member
  • *****
  • Posts: 1273
Re: Should this be a bug in Free Pascal?
« Reply #8 on: February 21, 2020, 06:04:35 am »
Quote
In this instance, if I were to call C2.Clone, I'd get back a class of type C2 (with no casting) whereas if I called C1.Clone, I'd get back a class of type C1.

As far as I understand, C1.Clone can be any of C1 or C2, while C2.Clone can be only C2. So, I can write procedure like:

Code: Pascal  [Select][+][-]
  1. Function Class1.Clone (Original: Class1) : Class1;
  2. Begin
  3.    if Original is Class2
  4.         then Result := Class2.Create  //  this kind of operation
  5.         else Result := Class1.Create;    
  6.    Result.Name := fName + ' cloned ' + Original.Name;
  7. End;
  8.  

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: Should this be a bug in Free Pascal?
« Reply #9 on: February 21, 2020, 08:12:38 am »
Use spaces in component names?
Specialize a type, not a var.

MoCityMM

  • Jr. Member
  • **
  • Posts: 72
Re: Should this be a bug in Free Pascal?
« Reply #10 on: March 15, 2020, 08:58:50 am »
I am thinking that 'yes' it should be a bug, put in the request...  >:D

 

TinyPortal © 2005-2018