I have a simple piece of code, that compiles in Delphi XE2 but not in XE3, and I don’t know why. I have reduced the problematic code to a small bit and would like to know what’s wrong with it in Delphi’s opinion. Trying to compile a project containing this unit in Delphi XE 2 works fine, but in Delphi XE3 (trial), it gives “[dcc32 Error] AffineTransform.pas(26): E2382 Cannot call constructors using instance variables”. The only “eccentric” thing I know of here is the use of the old-school “object” type, where the constructor isn’t really exactly the same thing as in real objects (TObject-based class instances).
If I replace the words ‘constructor’ in this object with ‘procedure’, then it compiles ok, but why is this, and is this an ok change to do in my code, i.e. is it a change that will have no effect on the functionality?
unit AffineTransform;
interface
type
{ Rectangular area. }
TCoordRect = object
public
Left, Top, Right, Bottom: Real;
constructor CreatePos(ALeft, ATop, ARight, ABottom: Real);
procedure Include(AX, AY: Real);
end;
implementation
constructor TCoordRect.CreatePos(ALeft, ATop, ARight, ABottom: Real);
begin
Left := ALeft;
Top := ATop;
Right := ARight;
Bottom := ABottom;
end;
procedure TCoordRect.Include(AX, AY: Real);
begin
CreatePos(AX, AY, AX, AY)
end;
end.
For this legacy Turbo Pascal style
object, there is really no meaning to the keywordconstructor. Although anobjectconstructor does have some special treatment, there’s absolutely no need for that here. What have here is nothing more than arecordwith some methods.The XE3 compiler was changed so that it no longer allows you to call a constructor on
Selfinside an instance method. That is the case for bothclassandobject. I’ve not seen any documentation of why this change was made. No doubt in time it will seep out.Your immediate solution is to replace
constructorwithprocedure. In the longer term, it would make sense to turn this into arecordrather than anobject.I would also council you to change the name of the method to
Initialize. Some library designers seem to opt for usingCreateandFreemethods on their records. This had led to immense amount of code being written like this:In fact all that code is spurious and can simply be removed! A
TRttiContextvariable will automatically initialize itself.That sort of design also sets a giant Heffalump Trap for that faction of Delphi coders that like to use
FreeAndNil. Passing a record toFreeAndNilleads to some interesting fireworks!