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

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

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

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/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Jonas Maebe-2

On 17 Nov 2009, at 10:02, Graeme Geldenhuys wrote:

> How to I solve this compiler hint?

Don't cast ordinals to pointers.

> ---------------------------------
> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Aleksa Todorovic-3
On Tue, Nov 17, 2009 at 10:05, Jonas Maebe <[hidden email]> 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?
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

dmitry boyarintsev
In reply to this post by Jonas Maebe-2
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
  b1:=@InData1;
  b2:=@InData2;
  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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Jonas Maebe-2
In reply to this post by Aleksa Todorovic-3

On 17 Nov 2009, at 10:17, Aleksa Todorovic wrote:

> On Tue, Nov 17, 2009 at 10:05, Jonas Maebe <[hidden email]> 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_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Graeme Geldenhuys
In reply to this post by Aleksa Todorovic-3
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/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Graeme Geldenhuys
In reply to this post by Jonas Maebe-2
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/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Jonas Maebe-2

On 17 Nov 2009, at 10:38, 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_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Graeme Geldenhuys
In reply to this post by dmitry boyarintsev
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.

>
> procedure XorBlock(var InData1, InData2; Size: longword);
> var
>   b1 : PByte; // in Delphi i'd use PByteArray
>   b2 ; PByte;
>   i: longword;
> begin
>   b1:=@InData1;
>   b2:=@InData2;
>   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/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Graeme Geldenhuys
In reply to this post by Jonas Maebe-2
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/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Graeme Geldenhuys
In reply to this post by dmitry boyarintsev
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;



Regards,
  - Graeme -

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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Graeme Geldenhuys
In reply to this post by dmitry boyarintsev
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/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

dmitry boyarintsev
In reply to this post by Graeme Geldenhuys
On Tue, Nov 17, 2009 at 12:48 PM, Graeme Geldenhuys
<[hidden email]> 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
  l1:=@inData1;
  l2:=@inData2;
  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
    b1:=@InData1;
    b2:=@InData2;
    for i:=(size-c) to size-1 do b1[i]:=b1[i] xor b2[i];
  end;
end;

thanks,
dmitry
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Graeme Geldenhuys
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/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re[2]: How to solve "Conversion between ordinals and pointers is not portable"

José Mejuto
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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Tomas Hajny
In reply to this post by Graeme Geldenhuys
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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

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

Paul Nicholls

----- Original Message -----
From: "Tomas Hajny" <[hidden email]>
To: <[hidden email]>; "FPC-Pascal users discussions"
<[hidden email]>
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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal