Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2009-11

How to solve "Conversion between ordinals and pointers is not portable"

17 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Graeme Geldenhuys

Hi,

How to I solve this compiler hint? I've managed to get DCPCrypt compiled and running successfully (with my current tests) under 64-bit FPC & Linux.

But I still have many compiler hints as listed below. Can I simply ignore them, or is there a way I can fix the code to remove the compiler warning. How serious is this hint?

/home/graemeg/programming/3rdParty/DCPcrypt/dcpcrypt2.pas(653,37) Hint:
Conversion between ordinals and pointers is not portable
---------------------------------
procedure XorBlock(var InData1, InData2; Size: longword);
var
  i: longword;
begin
  for i:= 1 to Size do
    Pbyte(PtrUInt(@InData1)+i-1)^ :=
       Pbyte(PtrUInt(@InData1)+i-1)^ xor
       Pbyte(PtrUInt(@InData2)+i-1)^;
end;
---------------------------------

1 2 3 4 5 6 7 123456789012345678901234567890123456789012345678901234567890123456789012345

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/

Reply by email

Jonas Maebe
to Graeme Geldenhuys
Graeme Geldenhuys wrote
How to I solve this compiler hint?

Don't cast ordinals to pointers.

Show quoted text 10 lines
--------------------------------- procedure XorBlock(var InData1, InData2; Size: longword); var i: longword; begin for i:= 1 to Size do Pbyte(PtrUInt(@InData1)+i-1)^ := Pbyte(PtrUInt(@InData1)+i-1)^ xor Pbyte(PtrUInt(@InData2)+i-1)^; end;

Replace the PtrUInt types casts with PByte (or Pointer) type casts.

Jonas

Reply by email

dmitry boyarintsev
to Jonas Maebe: Don't cast ordinals to pointers. Replace the PtrUInt types casts with PByte (or Pointer)…

Graeme, why don't you use power of the FPC (and it's pointer maths)? Pascal is language of readable code :)

procedure XorBlock(var InData1, InData2; Size: longword);
var
  b1 : PByte; // in Delphi i'd use PByteArray
  b2 ; PByte;
  i: longword;
begin
  ;
  ;
  for i:=0 to size-1 do
    b1[i]:=b1[i] xor b2[i];
end;

But, since we're using 32-bit processors it's more effective to use 32-bit xor (where possible)!

thanks,
dmitry

Reply by email

Jonas Maebe
to Aleksa Todorovic: Does that mean that (PByte(p) + N) = (Pointer(p) + N) for pointer-castable p and integer…
Aleksa Todorovic wrote 7 lines
On Tue, Nov 17, 2009 at 10:05, Jonas Maebe wrote: > > Replace the PtrUInt types casts with PByte (or Pointer) type casts. > Does that mean that (PByte(p) + N) = (Pointer(p) + N) for pointer-castable p and integer N?

Yes. The general rule is that adding an ordinal N to a pointer type P increases P by the size of the type this pointer points to times N. Sizeof(pbyte^) = sizeof(byte) = 1.

Pointer is a special case since it's untyped (sizeof(pointer^) = 0 in the FPC), and adding an ordinal N to an untyped pointer also increases its value by N.

Jonas

Reply by email

Graeme Geldenhuys
to Aleksa Todorovic: Does that mean that (PByte(p) + N) = (Pointer(p) + N) for pointer-castable p and integer…
Aleksa Todorovic wrote
Does that mean that (PByte(p) + N) = (Pointer(p) + N) for pointer-castable p and integer N?

I believe it does. I read in the ref.pdf document that when you increment a generic Pointer type, it increments by 1 (equal to 1 byte).

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/

Reply by email

Graeme Geldenhuys
to Jonas Maebe: Don't cast ordinals to pointers. Replace the PtrUInt types casts with PByte (or Pointer)…
Jonas Maebe wrote
> How to I solve this compiler hint? Don't cast ordinals to pointers.

:-)

Replace the PtrUInt types casts with PByte (or Pointer) type casts.

So in that case because a untyped parameters are treated like generic Pointer types whereby arithmetic increments in byte size, I don't actually need any type casts the parameters at all? Is the code below safe? It seem to work fine in our projects and data.

procedure XorBlock(var InData1, InData2; Size: longword);
var
  i: longword;
begin
  for i:= 1 to Size do
    Pbyte(@InData1+i-1)^ :=
       Pbyte(@InData1+i-1)^ xor
       Pbyte(@InData2+i-1)^;
end;

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/

Reply by email

Jonas Maebe
to Graeme Geldenhuys
Graeme Geldenhuys wrote
So in that case because a untyped parameters are treated like generic Pointer types whereby arithmetic increments in byte size, I don't actually need any type casts the parameters at all?

Indeed. In general, I'd recommend to always add a pointer typecast though, to avoid problems in case the declared type should ever change.

Jonas

Reply by email

Graeme Geldenhuys
to dmitry boyarintsev: Graeme, why don't you use power of the FPC (and it's pointer maths)? Pascal is language…
dmitry boyarintsev wrote
Graeme, why don't you use power of the FPC (and it's pointer maths)? Pascal is language of readable code :)

The original code is not mine, I'm simply making it 64-bit friendly and removing some compiler warnings where possible.

Show quoted text 11 lines
procedure XorBlock(var InData1, InData2; Size: longword); var b1 : PByte; // in Delphi i'd use PByteArray b2 ; PByte; i: longword; begin ; ; for i:=0 to size-1 do b1[i]:=b1[i] xor b2[i];
         ^      ^        ^
dcpcrypt2.pas(660,9) Error: Array type required

You are the second person to recommend something like this and every time I get compiler errors. I am using 64-bit FPC 2.4.0-rc1 under Linux.

But yes, your code is indeed more readable. :-)

But, since we're using 32-bit processors it's more effective to use 32-bit xor (where possible)!

I'm not using 32-bit processors. That's the whole reason for the modifications to DCPCrypt code - getting it 64-bit compatible.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/

Reply by email

Graeme Geldenhuys
to Jonas Maebe: Indeed. In general, I'd recommend to always add a pointer typecast though, to avoid…
Jonas Maebe wrote
Indeed. In general, I'd recommend to always add a pointer typecast though, to avoid problems in case the declared type should ever change.

Rather safe than sorry. I'll amend the code as such. Thanks for your help.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/

Reply by email

Graeme Geldenhuys
to dmitry boyarintsev: Graeme, why don't you use power of the FPC (and it's pointer maths)? Pascal is language…
dmitry boyarintsev wrote 5 lines
procedure XorBlock(var InData1, InData2; Size: longword); var b1 : PByte; b2 ; PByte;

Changing those declarations to PByteArray type solves the compiler error in FPC.

var
  b1: PByteArray;
  b2: PByteArray;

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/

Reply by email

Graeme Geldenhuys
to dmitry boyarintsev: Graeme, why don't you use power of the FPC (and it's pointer maths)? Pascal is language…
dmitry boyarintsev wrote
But, since we're using 32-bit processors it's more effective to use 32-bit xor (where possible)!

Out of interest... Could you explain "use 32-bit xor"? How does that differ to the code I posted?

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/

Reply by email

dmitry boyarintsev
to Graeme Geldenhuys: Changing those declarations to PByteArray type solves the compiler error in FPC. var b1:…
Graeme Geldenhuys wrote
Changing those declarations to PByteArray type solves the compiler error in FPC.

Seems like {$mode delphi} is used.

here's faster version of xorblock

procedure XorBlockEx(var InData1, InData2; Size: longword);
var
  l1 : PIntegerArray;
  l2 : PIntegerArray;
  b1 : PByteArray;
  b2 : PByteArray;
  i  : integer;
  c  : integer;
begin
  ;
  ;
  for i:=0 to size div sizeof(LongWord)-1 do
    l1[i]:=l1[i] xor l2[i];
  // the rest of the buffer (3 bytes)
  c:=size mod sizeof(longWord);
  if c>0 then begin
    ;
    ;
    for i:=(size-c) to size-1 do b1[i]:=b1[i] xor b2[i];
  end;
end;

thanks,
dmitry

Reply by email

Graeme Geldenhuys
to dmitry boyarintsev
dmitry boyarintsev wrote
Seems like {$mode delphi} is used.

Indeed it is. :)

here's faster version of xorblock

[...not that I fully understand the DCPCrypt code...]

Looking at your code and the rest of DCPCrypt code, it seems it already optimized the calls to xorblock(), instead of inside xorblock()....

Here is an example of a method using xorblock().

--------------------------------
procedure TDCP_blockcipher64.EncryptCBC(const Indata; var Outdata;
    Size: longword);
var
  i: longword;
  p1, p2: pointer;
begin
  if not fInitialized then
    raise EDCP_blockcipher.Create('Cipher not initialized');
  p1:= @Indata;
  p2:= @Outdata;
  for i:= 1 to (Size div 8) do
  begin
    Move(p1^,p2^,8);
    XorBlock(p2^,CV,8);
    EncryptECB(p2^,p2^);
    Move(p2^,CV,8);
    p1:= pointer(p1 + 8);
    p2:= pointer(p2 + 8);
  end;
  if (Size mod 8) 0 then
  begin
    EncryptECB(CV,CV);
    Move(p1^,p2^,Size mod 8);
    XorBlock(p2^,CV,Size mod 8);
  end;
end;
--------------------------------

Either way, to scratch my own itch, I am going to put together a small example app calling the original xorblock() and your xorblockex() recursively and do some timing around them to see the speed difference.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/

Reply by email

JoshyFun
to Graeme Geldenhuys

Hello Graeme,

Tuesday, November 17, 2009, 11:15:09 AM, you wrote:

GG> [...not that I fully understand the DCPCrypt code...]

GG> Looking at your code and the rest of DCPCrypt code, it seems it already GG> optimized the calls to xorblock(), instead of inside xorblock().... [...]

That's not an "optimization" it is a need because the EncryptECB can only work over 64 bits blocks, so the last block must be "padded". Also in 64 bits it should use 64 bits access to the array, not 32 bits always. In the "xorblockex" changing "LongWord" by "SizeUInt" and "PIntegerArray" by "PSizeUintArray" (which definition seems to not exist) should do the trick.

Best regards, JoshyFun

Reply by email

Tomas Hajny
to Graeme Geldenhuys: Changing those declarations to PByteArray type solves the compiler error in FPC. var b1:…
Graeme Geldenhuys wrote 13 lines
dmitry boyarintsev wrote: > > procedure XorBlock(var InData1, InData2; Size: longword); > var > b1 : PByte; > b2 ; PByte; Changing those declarations to PByteArray type solves the compiler error in FPC. var b1: PByteArray; b2: PByteArray;

I suggest being careful with PByteArray, or at least make sure that you know the type definition and you know where this definition comes from. First, it is certainly very different from PByte regarding the supported range. PByte allows addressing the complete memory space, PByteArray is limited (well, at least it is if you turn range checking on ;-) ). Moreover, PByte is defined in unit system and is thus common for all FPC programs, whereas there are several different definitions for PByteArray in the FPC RTL, out of which at least two are in common (cross-platform) units (in particular SysUtils and Objects), and there's a lot of other (3rd party / user) code containing other definitions of P/TByteArray.

Tomas

Reply by email

Paul Nicholls
to Tomas Hajny

----- Original Message -----

Earlier message 47 lines
From: "Tomas Hajny" To: ; "FPC-Pascal users discussions" Sent: Wednesday, November 18, 2009 10:40 PM Subject: Re: [fpc-pascal] How to solve "Conversion between ordinals and pointers is not portable" > On Tue, November 17, 2009 10:48, Graeme Geldenhuys wrote: >> dmitry boyarintsev wrote: >>> >>> procedure XorBlock(var InData1, InData2; Size: longword); >>> var >>> b1 : PByte; >>> b2 ; PByte; >> >> Changing those declarations to PByteArray type solves the compiler error >> in FPC. >> >> var >> b1: PByteArray; >> b2: PByteArray; > > I suggest being careful with PByteArray, or at least make sure that you > know the type definition and you know where this definition comes from. > First, it is certainly very different from PByte regarding the supported > range. PByte allows addressing the complete memory space, PByteArray is > limited (well, at least it is if you turn range checking on ;-) ). > Moreover, PByte is defined in unit system and is thus common for all FPC > programs, whereas there are several different definitions for PByteArray > in the FPC RTL, out of which at least two are in common (cross-platform) > units (in particular SysUtils and Objects), and there's a lot of other > (3rd party / user) code containing other definitions of P/TByteArray. > > Tomas Personally, I usual just declare my own definition of PByteArray when I need it just to be safe.... {Delphi Code} Type PByteArray = ^TByteArray; TByteArray = Array[0..MaxInt - 1] Of Byte; {/Delphi Code} cheers, Paul

Reply by email