[fpc-devel]Method overloading
Johann Glaser
Johann.Glaser at gmx.at
Tue Apr 29 12:20:42 CEST 2003
Hi!
I've got another problem with the compiler. Stripped down the problem,
it comes out that the compiler doesn't work correctly with overloaded
methods.
For example: Serial transmission of data, a base class:
CSerialInterface
which implements some methods for sending.
Send(Buf:Pointer;Length:LongInt); virtual; abstract;
Send(St:String); virtual;
Send(Buf:CCharBuffer); virtual;
(CCharBuffer is a class which is a "smart" char buffer)
Each serial interface type gets a descent class.
Type CRS232 = class(CSerialInterface) ... End;
Type CRS485 = class(CSerialInterface) ... End;
Type CRS422 = class(CSerialInterface) ... End;
(as examples). They only implement Send(Buf:Pointer;Length:LongInt);
And CSerialInterface implements the other Send methods which are only
wrappers for the above one (look at "virtual" and "virtual abstract"
declarations in CSerialInterface):
Procedure CSerialInterface.Send(St:String);
Begin
Send(@St[1],Length(St));
End;
(and analogous for the CCharBuffer method).
CRS232 now has 3 Send methods:
Send(Buf:Pointer;Length:LongInt); { implemented there }
Send(St:String); { inherited from CSerialInterface }
Send(Buf:CCharBuffer); { inherited from CSerialInterface }
Let's now look at the main program:
Var RS232 : CRS232;
Test : CSerialInterface;
St : String;
Begin
St := 'Hello World!';
RS232 := CRS232.Create;
RS232.Send(@St[1],Length(St)); { <-- works! }
RS232.Send(St); { compiler complains [1] }
Test := RS232;
Test.Send(St); { ugly crash [2] }
End.
[1] the compiler complains
Error: Wrong amount of parameters specified
what means, that it it didn't find the Send(St:String) method. Despite
it is inherited!!!
[2] here the compiler seems to have a problem with the VMT and the
location each overloaded method gets in the VMT. First it calls
CSerialInterface.Send(St:String) (which is called correct). This method
then calls Send(Buf:Pointer;Length:LongInt).
Therefore the VMT was invented to find the "most actual" method.
CSerialInterface.Send(St:String) gets the VMT of CRS232 (as hidden
parameter) and so calls CRS232.Send(Buf:Pointer;Length:LongInt).
Paff! Crash! The compiler seems to use another one of the 3 Send methods
from the VMT. Namely the Send(St:String). Which calls itself
recursively. And with the wrong parameter and even the wrong parameter
count.
I didn't try exactly the setup described here. Please have a look at the
attached file. It contains a few units demonstrating the problem.
Please use "ulimit -s 256" before executing "./bar". This limits the
stack and prevents a complete crash of your computer.
BTW: I'm using
Free Pascal Compiler version 1.0.6 [2002/08/10] for i386
in my Debian Linux (sid).
BTW: Strange: sometimes it has the problem as described and sometimes it
even doesn't identify the Test.Send(St) correctly.
Please try using "fpc bar.pas" and "fpc -B bar.pas" several times. Then
the problem occurs in different ways. Strange.
Bye
Hansi
--
Johann Glaser <Johann.Glaser at gmx.at>
Vienna University of Technology
Electrical Engineering
____ http://www.johann-glaser.at/ ____
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug-hansi.tar.gz
Type: application/x-gzip
Size: 759 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20030429/aea744ee/attachment.bin>
More information about the fpc-devel
mailing list