Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will const parameters and typecasting work as before under Delphi 64bit?

As a general rule I have circumvented a lot of classical design traps when using pointers by taking advantage of Const (untyped) parameters rather than hard coded types. This gives me the benefit of speed when executing advanced graphical functions while leaving the technical details up to the compiler. It has also made it easy to use the same code in Delphi and Free Pascal with minimal changes.Lately however, I have begun to question this due to Embarcadero's vauge statements on the evolution of Delphi and it's upcomming safety model.

For instance, concider the following example:

Type TSomeDataProc = procedure (const aInput;var aOutput) of Object;

(* Convert 8-bit pixel to 16-bit pixel *)
Procedure TMyClass.ProcessSomeData08x565(Const aInput;var aOutput);
var r,g,b: Byte;
Begin
  FPalette.ExportTriplets(Byte(aInput),r,g,b);
  Word(aOutput):=(R SHR 3) SHL 11 or (G SHR 2) SHL 5 or (B SHR 3);
End;

(* Convert 16-bit pixel to 24-bit pixel *)
Procedure TMyClass.ProcessSomeData565x888(Const aInput;var aOutput);
Begin
  With TRGBTriple(aOutput) do
  Begin
   rgbtRed:=(((word(aInput) and $F800) shr 11) shl 3);
   rgbtGreen:= (((word(aInput) and $07E0) shr 5) shl 2);
   rgbtBlue:= ((word(aInput) and $001f) shl 3);
  end;
End;

We now have two procedures with identical declarations, but they handle the pixeldata very differently. This gives us the benefit of using a lookup table to get the correct "converter" method. This should be done in either the constructor or wherever the picture bitmap is allocated, like this:

Private
FLookup: Array[pf8bit..pf32bit,pf8bit..pf32bit] of TSomeDataProc;

Procedure TMyClass.Create;
Begin
  Inherited;
  FLookup[pf8bit,pf16bit]:=ProcessSomeData08x565;
  FLookup[pf16bit,pf24Bit]:=ProcessSomeData565x888;
end;

Whenever we need to convert pixels we simply look up the correct method and use it. The syntax remains the same for all the procedures - so we dont have to worry about "how" each procedure operates. As far as our class is concerned, they all look the same.

Procedure TMyClass.ConvertTo(aFormat:TpixelFormat);
Begin
 // Get function for the correct pixel converter
 FConvertProc:=FLookup[CurrentFormat,aFormat];

 //Use the pixel converter
 FConvertProc(GetSourcePixelAddr(x,y),GetTargetPixelAddr(x,y));
end;

The question is: Will this kind of typecasting (e.g: Const to Byte or any defined Record type) survive under 64bit? I personally cant see why not, but Embarcadero have been sort of vague regarding the new "safety" model and pointer-use, so I find it a bit hard to safeguard my code for the future.

like image 226
Jon Lennart Aasenden Avatar asked Jan 31 '11 14:01

Jon Lennart Aasenden


2 Answers

Since such tricks are used in the RTL, I don't see deprecating a var or const typeless parameter without a lot of code breaking.

Embarcadero tries its best to maintain as much backward compatibility as possible.

They even should include back the inline asm in the 64 bit compiler, after having first made some notification about the use of an external assembler.

And such a modification won't have anything to do with the 64 bit model, whereas the x86-64 assembler was a new piece of code to write.

So you should post this question of the official Embarcadero newsgroup, but I think you don't have to worry about this.

like image 77
Arnaud Bouchez Avatar answered Oct 21 '22 20:10

Arnaud Bouchez


Note that FPC already did change the CONST parameter, though not in this case.

For the normal case, CONST is not guaranteed by reference anymore for all calling conventions, but follows whatever the respective ABI specifies. A new parameter type, CONSTREF is guaranteed to be by reference.

Like all breakage of compatibility it is the problem that in TP/Delphi CONST is always by ref, but TP/Delphi is also always x86.

Among others all STDCALL functions change, like e.g. IUnknown.Queryinterface:

http://wiki.freepascal.org/User_Changes_Trunk#IInterface.QueryInterface.2C_._AddRef_and_._Release_definitions_have_been_changed

The reason is more or less that in these cases, x86 ABI information entered the generic interface, something which is not cross-architecture compatible. So one has to guess if it is part of the language, or part of the x86 implementation of the language.

Note that IUnknown is also used on other platforms for e.g. Firefox' XPCOM

Delphi might also hit such snags, but I think they primarily will effect functions/methods with explicit calling convention requirements, because one can change the internal convention to suit needs, but one can't practically change the rest of the world ((XP)COM or existing C(++) libraries) to suit existing code in Delphi

like image 45
Marco van de Voort Avatar answered Oct 21 '22 20:10

Marco van de Voort