Главная страница | назад





Article #19539: EStackOverflow and TForm constructors

 Question and Answer Database

FAQ4539C.txt - EStackOverflow and TForm constructors

Category   :VCL
Platform   :All-32Bit
Product    :C++Builder4.x,   

Question:
I have a second TForm constuctor that takes and int
as the second argument. When I call it, I blow the stack.
What's wrong with it?

Answer:
This is the result of a bug in the VCL. In pascal, TForm 
has an alternate constructor called CreateNew. However, 
in C++ the name of the constructor must be the same name 
as the class, so the constructor could not be name 
CreateNew in C++Builder. 
So, a constructor with a dummy int argument was used to 
represent CreateNew.

The dummy argument is an integer value. The argument doesn't
do anything. The integer argument is used to specify a 
different type of constructor. You can see the dummy 
constructor in forms.hpp

public:
 __fastcall virtual TCustomForm(Classes::TComponent* AOwner);
 __fastcall TCustomForm(Classes::TComponent* AOwner, int Dummy);

The first constructor equates to TCustomForm.Create 
and the second equates to TCustomForm.CreateNew.

Here's the problem. In Delphi, constructors can be virtual. 
In BCB3, CreateNew was not virtual, but in BCB4, it is. 
So, by creating a form class that takes an integer argument, 
you have unwittingly overriden CreateNew.
There is one final catch that causes the stack overflow. 
TCustomForm.Create calls TCustomForm.CreateNew.

So here is how the path of execution goes. When the 
constructor for TForm2 is called, control is immediately 
passed to TCustomForm::Create. Create then calls CreateNew. 
Your constructor overrides CreateNew, so the constructor
for TForm2 is called again. Control immediately passes into
TCustomForm::Create, and the whole process is repeated forever.

The workaround is to not have constructors that take an 
integer and an owner argument: 
TForm2(TComponent *Owner, int value). 
Pick some other argument pattern. Put the integer first, or 
try making it a long instead, or maybe an unsigned int.
Borland is aware of this bug.

5/25/99 11:46:57 AM
 

Last Modified: 01-SEP-99