Wednesday, November 23, 2011

Making Integer 4 bytes for x64 target comes with price

A whole generation of programmers grew in assumption that Integer and Pointer will be the same size forever.

function EventToVariant(const AMethod: TNotifyEvent): Variant;
begin
  Result := 'vgmet' + IntToHex(Integer(TMethod(AMethod).Data), 8) + IntToHex(Integer(TMethod(AMethod).Code), 8);
end;
The generic integer types are Integer and Cardinal, use these whenever possible, since they result in the best performance for the underlying CPU and operating system.
So they use them whenever possible.
function ObjectToVariant(const AObject: TObject): Variant;
begin
  Result := 'vgobj' + IntToStr(Integer(Pointer(AObject)));
end;
Sometime its hard to see any problem at all.
    TMethod(Result).Data := Pointer(StrToInt('$' + Copy(S, 6, 8)));
    TMethod(Result).Code := Pointer(StrToInt('$' + Copy(S, 14, 8)));

(Source code snippets taken from FMX.Types unit).

Yes, probably most of the pointers are way below 4GB. Methods will probably always be there (unless you manage to set the image base above that range). But the larger your project grow, the sooner it will start producing pointers above 4GB, and its the time when FireMonkeys' DataBinding (which relies heavily on the code above) may fail.