<div dir="auto"><div><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">Martin Frb via fpc-devel <<a href="mailto:fpc-devel@lists.freepascal.org">fpc-devel@lists.freepascal.org</a>> schrieb am Mo., 20. Okt. 2025, 22:29:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 17/10/2025 21:15, Sven Barth via fpc-devel wrote:<br>
>> What is the best way to check if a virtual function in a base class <br>
>> has been overridden by a class that inherits the base class?<br>
>><br>
>> In LCL TPrinter.pas the following check is used:<br>
>><br>
>><br>
>> procedure TPrinter.NewPage;<br>
>> begin<br>
>>   Inc(fPageNumber);<br>
>>   if TMethod(@Self.DoNewPage).Code = Pointer(@TPrinter.DoNewPage) then<br>
>>     begin<br>
>>     ..<br>
>>     end<br>
>>  ..<br>
>> end<br>
>><br>
>> We have run across an optimization problem with the TCocoaPrinter <br>
>> class and that TPrinter code.<br>
>><br>
>> TCocoaPrinter = class(TPrinter)<br>
>><br>
>> with no override of DeNewPage<br>
><br>
> David's problem is *not* due to a corruction or a bug, but due to an <br>
> optimization that FPC performs that leads to different behavior, <br>
> namely changing virtual methods that are empty to EmptyMethod to <br>
> reduce the number of duplicate (empty) methods in the binary.<br>
<br>
I am trying to figure out under which circumstances this would happen?<br>
   TPrinter = class...<br>
      procedure DoNewPage; virtual;<br>
<br>
And the check really only makes sense for virtual methods. Well (in <br>
generics that differs, but for non virtual, both classes are known at <br>
compiletime).<br>
<br>
So if it is a virtual method:<br>
<br>
If the compiler optimizes @TPrinter.DoNewPage to EmptyMethod, then it <br>
would put that into the class definition?<br>
So that is into the VMT?<br>
And there is only one VMT?<br>
And self is a pointer (to pointer) to that one VMT?<br>
<br>
So then how can one be replaced, but the other not?<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">If one is compiled with -O3, but the other is compiled with -O2. The VMT is created for each type, so even if a method isn't overridden it can be replaced in one VMT, but not in the other. </div><div dir="auto"><br></div><div dir="auto">In this case I suspect the LCL and thus TPrinter is compiled with -O2 and the custom code with -O3.</div><div dir="auto"><br></div><div dir="auto">Regards, </div><div dir="auto">Sven </div></div>