Sign in Join

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

Mailing lists / fpc-devel / 2019-03

Packed record integers and x86_86

11 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

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

DJ Coertzen

Hi there,

I need a solution for a packed record containing 4-byte 32-bit integers and cardinals, and other byte 8 bit and word 16 bit sized variables to overlay over a stream.

Example:
*type*
* TMyBinaryHeader = packed record*
* Sender : Cardinal;*

* Target : Cardinal;*

* Reference : Integer; *

* Flags : Word;*
* CheckByte : Byte;*
* end;*

So on 32 bit systems, SizeOf(TMyBinaryHeader) will report 15 bytes. How do I accomplish this on 64 bit platform and avoiding "myprotocollib.pas(x,y) Error: Typecast has different size (4 -> 8) in assignment" without having to port to ugly byte copy operations.

Thanks.

Reply by email

Sven Barth
to DJ Coertzen

DJ Coertzen schrieb am Mi., 27. März 2019,
18:27:

Show quoted text 24 lines
Hi there, I need a solution for a packed record containing 4-byte 32-bit integers and cardinals, and other byte 8 bit and word 16 bit sized variables to overlay over a stream. Example: *type* * TMyBinaryHeader = packed record* * Sender : Cardinal;* * Target : Cardinal;* * Reference : Integer; * * Flags : Word;* * CheckByte : Byte;* * end;* So on 32 bit systems, SizeOf(TMyBinaryHeader) will report 15 bytes. How do I accomplish this on 64 bit platform and avoiding "myprotocollib.pas(x,y) Error: Typecast has different size (4 -> 8) in assignment" without having to port to ugly byte copy operations.

Would you show the code at/around the error location, please? I suspect that it isn't the record that's the problem, but how you use it.

Regards,
Sven

Reply by email

Christo Crause
to DJ Coertzen: I need a solution for a packed record containing 4-byte 32-bit integers and cardinals,…
Show quoted text 24 lines
Hi there, I need a solution for a packed record containing 4-byte 32-bit integers and cardinals, and other byte 8 bit and word 16 bit sized variables to overlay over a stream. Example: *type* * TMyBinaryHeader = packed record* * Sender : Cardinal;* * Target : Cardinal;* * Reference : Integer; * * Flags : Word;* * CheckByte : Byte;* * end;* So on 32 bit systems, SizeOf(TMyBinaryHeader) will report 15 bytes. How do I accomplish this on 64 bit platform and avoiding "myprotocollib.pas(x,y) Error: Typecast has different size (4 -> 8) in assignment" without having to port to ugly byte copy operations.

Perhaps use size explicit types such as uint32 and int32?

Reply by email

DJ Coertzen
to Christo Crause
PM Christo Crause wrote 35 lines
On Wed, 27 Mar 2019, 19:27 DJ Coertzen, wrote: > Hi there, > > I need a solution for a packed record containing 4-byte 32-bit integers > and cardinals, and other byte 8 bit and word 16 bit sized variables to > overlay over a stream. > > Example: > *type* > * TMyBinaryHeader = packed record* > * Sender : Cardinal;* > > * Target : Cardinal;* > > * Reference : Integer; * > > * Flags : Word;* > * CheckByte : Byte;* > * end;* > > So on 32 bit systems, SizeOf(TMyBinaryHeader) will report 15 bytes. How > do I accomplish this on 64 bit platform and avoiding > "myprotocollib.pas(x,y) Error: Typecast has different size (4 -> 8) in > assignment" without having to port to ugly byte copy operations. > Perhaps use size explicit types such as uint32 and int32? _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Pointer arithmetic:
*for Indx := 0 to SizeOf(TTCPPackageHeader) - 1 do Dec(Byte(Pointer(Cardinal(@x) + Indx)^), ARollCount);*

Reply by email

DJ Coertzen
to Christo Crause: Perhaps use size explicit types such as uint32 and int32?
PM Christo Crause wrote 34 lines
On Wed, 27 Mar 2019, 19:27 DJ Coertzen, wrote: > Hi there, > > I need a solution for a packed record containing 4-byte 32-bit integers > and cardinals, and other byte 8 bit and word 16 bit sized variables to > overlay over a stream. > > Example: > *type* > * TMyBinaryHeader = packed record* > * Sender : Cardinal;* > > * Target : Cardinal;* > > * Reference : Integer; * > > * Flags : Word;* > * CheckByte : Byte;* > * end;* > > So on 32 bit systems, SizeOf(TMyBinaryHeader) will report 15 bytes. How > do I accomplish this on 64 bit platform and avoiding > "myprotocollib.pas(x,y) Error: Typecast has different size (4 -> 8) in > assignment" without having to port to ugly byte copy operations. > Perhaps use size explicit types such as uint32 and int32? _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

I discovered UInt32 in the meanwhile . Thanks. I replied on the wrong response about pointer arithmetic

Reply by email

DJ Coertzen
to Sven Barth: DJ Coertzen schrieb am Mi., 27. März 2019, 18:27: Would you show the code at/around the…

On Wed, Mar 27, 2019 at 7:47 PM Sven Barth via fpc-devel <

Show quoted text 39 lines
wrote: DJ Coertzen schrieb am Mi., 27. März 2019, 18:27: > Hi there, > > I need a solution for a packed record containing 4-byte 32-bit integers > and cardinals, and other byte 8 bit and word 16 bit sized variables to > overlay over a stream. > > Example: > *type* > * TMyBinaryHeader = packed record* > * Sender : Cardinal;* > > * Target : Cardinal;* > > * Reference : Integer; * > > * Flags : Word;* > * CheckByte : Byte;* > * end;* > > So on 32 bit systems, SizeOf(TMyBinaryHeader) will report 15 bytes. How > do I accomplish this on 64 bit platform and avoiding > "myprotocollib.pas(x,y) Error: Typecast has different size (4 -> 8) in > assignment" without having to port to ugly byte copy operations. > Would you show the code at/around the error location, please? I suspect that it isn't the record that's the problem, but how you use it. Regards, Sven > _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Pointer arithmetic:
*for Indx := 0 to SizeOf(TTCPPackageHeader) - 1 do Dec(Byte(Pointer(Cardinal(@x) + Indx)^), ARollCount);*

Reply by email

Pierre Muller
to DJ Coertzen
Show quoted text 7 lines
_______________________________________________ fpc-devel maillist  -  http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel Pointer arithmetic: *for Indx := 0 to SizeOf(TTCPPackageHeader) - 1 do Dec(Byte(Pointer(Cardinal(@x) + Indx)^), ARollCount);*

the error has nothing to do with your record,
its that part:
Pointer(Cardinal(@x) + Indx)^)

The problem is that Cardinale is an unsigned 32-bit integer, while on 64-bit, you will need UINT64,

You should use PtrUInt type that is an unsigned type that always have the size of an address instead of cardinal here!

Pierre

Reply by email

J. Gareth Moreton

I think the official unsigned 32-bit integer type in Pascal is "LongWord". As others have said, be aware that pointers are 64-bit under x64... that's kind of why it's called x64!  If you absolutely must have a packed record with 32-bit types, I recommend changing Sender and Target to indices that are added to a base address.
Similar to what Pierre said, change your Pointer code to something like this:
for Indx := 0 to SizeOf(TTCPPackageHeader) - 1 do
Dec(Byte(Pointer(PtrUInt(@x) + Indx)^), ARollCount);

So similarly with your record, instead of directly derefencing Sender and Target - since I assume your record type must stay fixed at 15 bytes - have something akin to "Pointer(PtrUInt(@BaseAddr) + Sender)".

The first rule, first and foremost... don't assume the Pointer is a fixed size.  Hope all of this helps.

Gareth aka. Kit
P.S. I would recommend adding a "Filler" or "Reserved" byte at the end of your record type to make it 16 bytes long - such a size is more efficient when it's part of an array in memory.

On Wed 27/03/19 21:11 , Pierre Muller sent:

_______________________________________________ fpc-devel maillist  -  http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

[2]">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Pointer arithmetic: *for Indx := 0 to SizeOf(TTCPPackageHeader) - 1 do

Dec(Byte(Pointer(Cardinal(@x) + Indx)^), ARollCount);* the error has nothing to do with your record,
its that part:
Pointer(Cardinal(@x) + Indx)^)

The problem is that Cardinale is an unsigned 32-bit integer, while on 64-bit, you will need UINT64,

You should use PtrUInt type that is an unsigned type that always have the size of an address instead of cardinal here!

Pierre

Reply by email

J. Gareth Moreton

Heh, much better - thank you!

On Thu 28/03/19 14:31 , "Karoly Balogh (Charlie/SGR)" sent:
Hi,

J. Gareth Moreton wrote 12 lines
I think the official unsigned 32-bit integer type in Pascal is "LongWord". As others have said, be aware that pointers are 64-bit under x64... that's kind of why it's called x64!  If you absolutely must have a packed record with 32-bit types, I recommend changing Sender and Target to indices that are added to a base address. Similar to what Pierre said, change your Pointer code to something like this: for Indx := 0 to SizeOf(TTCPPackageHeader) - 1 do
Dec(Byte(Pointer(PtrUInt(@x) + Indx)^), ARollCount);

How about Dec(PByte(@x)[Indx], ARollCount); instead? That doesn't look like an angry C programmer tried to convert some abomination to Pascal, and works on all pointer sizes.

(Unless it also has to compile with say, Delphi.)

Charlie

Reply by email

Karoly Balogh (Charlie/SGR
to J. Gareth Moreton: I think the official unsigned 32-bit integer type in Pascal is "LongWord". As others have…

Hi,

J. Gareth Moreton wrote 10 lines
I think the official unsigned 32-bit integer type in Pascal is "LongWord". As others have said, be aware that pointers are 64-bit under x64... that's kind of why it's called x64!  If you absolutely must have a packed record with 32-bit types, I recommend changing Sender and Target to indices that are added to a base address. Similar to what Pierre said, change your Pointer code to something like this: for Indx := 0 to SizeOf(TTCPPackageHeader) - 1 do Dec(Byte(Pointer(PtrUInt(@x) + Indx)^), ARollCount);

How about Dec(PByte(@x)[Indx], ARollCount); instead? That doesn't look like an angry C programmer tried to convert some abomination to Pascal, and works on all pointer sizes.

(Unless it also has to compile with say, Delphi.)

Charlie

Reply by email