Virtual methods with inline hint violate polymorphism
Original Reporter info from Mantis: CuriousKit @CuriousKit
-
Reporter name: J. Gareth Moreton
Original Reporter info from Mantis: CuriousKit @CuriousKit
- Reporter name: J. Gareth Moreton
Description:
If a virtual method in a class is implemented with the 'inline' hint, and a descendant class overrides it, compiled code will sometimes cause the inlined ancestor method to be called regardless of the class type of the object in question, thus violating some of the principles of object-oriented programming.
A little difficult to explain, but take a look at the code sample below for a demonstration:
Steps to reproduce:
Write the following program:
----
program InlineClass;
type
TAncestor = class
public
procedure TestMethod; virtual;
end;
TDerived = class(TAncestor)
public
procedure TestMethod; override;
end;
procedure TAncestor.TestMethod; inline; // Virtual method with an 'inline' hint.
begin
WriteLn('Ancestor Method');
end;
procedure TDerived.TestMethod;
begin
WriteLn('Derived Method');
end;
var
TestClass: TAncestor;
begin
TestClass := TDerived.Create;
try
TestClass.TestMethod; // <-- TAncestor.TestMethod is called instead of TDerived.TestMethod
finally
TestClass.Free;
end;
Write('Press any key to exit...');
ReadLn();
end.
----
Though the "TestClass" variable is of type TAncestor, an object of type TDerived is instantiated. However, when executed, TAncestor.TestMethod is called instead (or more correctly, the method's code put in place of the call). Removing the "inline" hint will result in the correct behaviour of TDerived.TestMethod being called.
i.e. When "inline" is present, the following is printed:
Ancestor Method
Press any key to exit...
When inline is removed, the following is printed instead:
Derived Method
Press any key to exit...
Additional information:
Whether or not this is a bug, I would at least consider it unexpected behaviour.
I would recommend either the "inline" hint being ignored on virtual methods (with a compiler warning) or, better, only honour the "inline" hint if the compiler can be absolutely certain that it should be calling the inlined method and not an overridden version (e.g. in the case of a class variable, knowing for sure what the current object's class type is and it being impossible to be anything else - an example would be in the code sample above, where it can't be anything but an object of type TDerived).
Mantis conversion info:
- Mantis ID: 32605
- OS: Microsoft Windows
- OS Build: 7 Enterprise
- Build: Developmental Branch
- Platform: PC Intel x86-64
- Version: 3.1.1
- Fixed in version: 3.1.1
- Fixed in revision: 37887 (#672afcdc)
- Monitored by: » @CuriousKit (J. Gareth Moreton)