i have a base class declarated like this
type
TBaseClass=class
protected
constructor Create(LoadData:boolean;const Param1,Param2:string); overload;
public
Destructor Destroy; override;
end;
Now in another unit a child class TChid_Class which descend from TBaseClass
TChid_Class=class(TBaseClass)
function Create(const Param1, Param2 : String;const Param3 : OleVariant ; var Param4 : LongInt): Integer;overload;
constructor Create; overload;
constructor Create(LoadData:boolean); overload;
end;
in this class exist a function called Create like the constructors, the problem is , when i try to create a instance to the TChid_Class i have an access violation.
i wrote this small console app which show the problem
program TestClass;
{$APPTYPE CONSOLE}
uses
Variants,
SysUtils;
type
TBaseClass=class
protected
constructor Create(LoadData:boolean;const Param1,Param2:string); overload;
public
Destructor Destroy; override;
end;
TChid_Class=class(TBaseClass)
function Create(const Param1, Param2 : String;const Param3 : OleVariant ; var Param4 : LongInt): Integer;overload;
constructor Create; overload;
constructor Create(LoadData:boolean); overload;
end;
{ TBaseClass }
constructor TBaseClass.Create(LoadData: boolean; const Param1, Param2: string);
begin
inherited Create;
Writeln('constructor TBaseClass.Create(LoadData: boolean; const Param1, Param2: string);');
end;
destructor TBaseClass.Destroy;
begin
//Code
inherited;
end;
{ TChid_Class }
function TChid_Class.Create(const Param1, Param2: String; const Param3: OleVariant; var Param4: Integer): Integer;
begin
Writeln('function create');
Result:=0;
end;
constructor TChid_Class.Create;
begin
Writeln('constructor TChid_Class.Create');
Create(True);
end;
constructor TChid_Class.Create(LoadData: boolean);
begin
Writeln('constructor TChid_Class.Create(LoadData: boolean)'); //here is the access violation
Create(LoadData,'Value 1','Value 2');
end;
var
Invoker : TChid_Class;
Pid : integer;
begin
try
Invoker:=TChid_Class.Create;
try
Invoker.Create('','',Unassigned,Pid)
finally
Invoker.Free;
end;
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
readln;
end.
if i rename the function create, the problem is go away, but i am looking for a solution without rename the create function or the constructors.
using delphi 2007
Thanks in advance.
With Delphi 7 I get an AV too. Renaming the method or moving it (as suggested by Sertac Akyuz) fixes the AV.
What I discovered by looking at the assembler:
When creating a new object a non-zero value is placed in register dl before calling the constructor.
mov dl,$01 // dl set to 1
mov eax,[$00401268]
call TChild_Class.Create
Then in the constructor, on the begin line, ClassCreate is called when dl is non-zero.
test dl,dl
jz +$08 //if dl = 0 then do not call ClassCreate
add esp,-$10
call -$00000396 //calls ClassCreate
But then it goes wrong, with your code, the compiler sets dl to 1 again before calling Create(True), so on the begin line of TChid_Class.Create(LoadData: boolean);, ClassCreate is called again which results in an AV.
After renaming your function or moving its declaration, the compiler clears dl (xor edx,edx) instead of setting it to 1, before calling Create(True).
My guess is that it is a bug in the Delphi compiler which is fixed in Delphi 2010 and higher.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With