[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