Recent

Author Topic: need workaround for bit fields bug  (Read 2432 times)

440bx

  • Hero Member
  • *****
  • Posts: 6130
Re: need workaround for bit fields bug
« Reply #30 on: January 05, 2026, 10:57:45 am »
a qword is aligned on an 8 byte address and that is how it is in both 32bit and 64bit.

The reason is: the type is an 8 byte type, therefore its alignment is on an 8 byte address and that's independent of bitness.

if you need to convince yourself, write a little program that uses types that include one or more qword fields and you'll see they will all be aligned on an 8 byte address as they should be, whether the program is 32bit or 64bit.

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 18764
  • To Europe: simply sell USA bonds: dollar collapses
Re: need workaround for bit fields bug
« Reply #31 on: January 05, 2026, 11:13:30 am »
What I mean is not the initial alignment, but the secondary alignment for the record members.
You can force the initial alignment to be 8 bytes, You know that.
For a 64 bit value to be interpreted correctly on a 32 bit platform, the record should be (bit) packed. (and it is)
If you do not do that correctly, the members will also be 8 byte aligned and that is wrong.

I frankly do not understand that you would interpret it otherwise.

What I agree with you, but will not test, is that if the compiler does not adhere to its own specifications there may be a bug. (I don't have 32 bit compilers for 64 bit platforms anymore except D7 under win11. I even dropped your beloved D2..    :-X )
« Last Edit: January 05, 2026, 11:22:33 am by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

440bx

  • Hero Member
  • *****
  • Posts: 6130
Re: need workaround for bit fields bug
« Reply #32 on: January 05, 2026, 12:06:12 pm »
For a 64 bit value to be interpreted correctly on a 32 bit platform, the record should be (bit) packed. (and it is)
If you do not do that correctly, the members will also be 8 byte aligned and that is wrong.
Absolutely NOT.  The last thing you or any programmer wants is structures to be different because of alignment, which is completely unnecessary and unwarranted.

IOW, _all_ members, regardless of type must be aligned the same way in 32 bit and 64 bit EXCEPT if the record is packed (which is one of the reasons records are _rarely_ packed - it causes portability problems from one bitness to another.)

The compiler will align a qword on an 8 byte boundary _as it should_ with a possible exception when it is a field in a packed record.


FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 18764
  • To Europe: simply sell USA bonds: dollar collapses
Re: need workaround for bit fields bug
« Reply #33 on: January 05, 2026, 01:24:51 pm »
You seem to forget that for the 32 bit compiler to interpret a 64 bit value it is necessary for the fields to be bit aligned? How would you suggest to make that otherwise?  ::)

Good luck with your, frankly funny, quests... :-X

E.g. for 32 bit platforms that are lo:
Code: Pascal  [Select][+][-]
  1. {$ifdef cpu32}
  2. type
  3.    Int64 = bitpacked record
  4.      hi:longint;
  5.      lo:cardinal;
  6. end;
  7. {$endif}
This guarantees compatibility with 64 bit where Int64 is a native type.
And how the compiler treats it.
« Last Edit: January 05, 2026, 01:40:38 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

440bx

  • Hero Member
  • *****
  • Posts: 6130
Re: need workaround for bit fields bug
« Reply #34 on: January 05, 2026, 04:57:58 pm »
a qword is aligned on an 8 byte boundary.  That has NOTHING to do with bit alignment.  It's the data type's _natural_ alignment and that is independent of bitness and, again, has absolutely nothing to do with bit packing bit fields (just in case, a qword isn't a bit field, it's an 8 byte data type.)

Stop misleading people.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 18764
  • To Europe: simply sell USA bonds: dollar collapses
Re: need workaround for bit fields bug
« Reply #35 on: January 05, 2026, 05:08:06 pm »
A qword (64 bit) is not a native type on 32 bit: the compiler uses a record.
Stop misleading people.
It uses at least two registers being direct or alternatively indirect with a single pointer dereference []. On your beloved Windows usually eax/edx for passing or a memory reference (indirect), whereas a 64 bit windows uses the whole value in rcx, but can also use a pointer reference(indirect).
If that is all you do not understand I won't spend much more time on the subject.

I am not by any means misleading: a 64 bit value is represented as an internal record on a 32 bit compiler, so you have to make sure the record alignment is correct.
(It is also the reason that on 32 bit compilers a 64 bit value does not behave as a true ordinal)
« Last Edit: January 05, 2026, 05:21:18 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

440bx

  • Hero Member
  • *****
  • Posts: 6130
Re: need workaround for bit fields bug
« Reply #36 on: January 05, 2026, 05:20:35 pm »
A qword (64 bit) is not a native type on 32 bit: the compiler uses a record.
Stop smoking red paint for breakfast.  a qword is not a record.

a qword is not an ordinal type, therefore as you correctly said (the only thing that is correct in your reply) in 32 bit it is not a native type but that doesn't change how it is aligned.

For the record and, as you _incorrectly_ stated in a previous post, it is NOT aligned on a 4 byte boundary.

Go write a few test programs for you to see how a qword is aligned.


FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 18764
  • To Europe: simply sell USA bonds: dollar collapses
Re: need workaround for bit fields bug
« Reply #37 on: January 05, 2026, 05:22:35 pm »
It IS internally a record on 32 bit, just like it is prepared for 128 bit: examine the compiler sources.
There is one exception if the X87 floating point registers are used.
See:
https://www.freepascal.org/docs-html/ref/refsu4.html

Documented.

The reason for the remark in the documentation is just because on a 32 bit platform a 64 bit value can not be handled as a single entity. For the purpose of as much compatibility as possible, the 32 bit compiler handles a 64 bit value as a bitpacked record.
« Last Edit: January 05, 2026, 05:32:46 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

440bx

  • Hero Member
  • *****
  • Posts: 6130
Re: need workaround for bit fields bug
« Reply #38 on: January 05, 2026, 06:52:05 pm »
It IS internally a record on 32 bit, just like it is prepared for 128 bit: examine the compiler sources.
What it is internally is irrelevant. 

The only thing that is relevant is that it will be aligned on an 8 byte boundary. Period.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

jamie

  • Hero Member
  • *****
  • Posts: 7589
Re: need workaround for bit fields bug
« Reply #39 on: January 05, 2026, 11:07:23 pm »
Thaddy must have been a lawyer at one time in his many lives, just not a good one! :o

The only true wisdom is knowing you know nothing

creaothceann

  • Sr. Member
  • ****
  • Posts: 278
Re: need workaround for bit fields bug
« Reply #40 on: January 06, 2026, 11:30:34 am »
Go write a few test programs for you to see how a qword is aligned.

For those who want to try:

Code: Pascal  [Select][+][-]
  1. program AlignmentTest;  // 32-bit x86
  2.  
  3.  
  4. {$warn 4055 off: conversion between ordinals and pointers is not portable}
  5.  
  6.  
  7. type
  8.         TAlignmentTest_0 = record  {_ : array[1..0] of byte;}  Data : QWord;  end;
  9.         TAlignmentTest_1 = record   _ : array[1..1] of byte;   Data : QWord;  end;
  10.         TAlignmentTest_2 = record   _ : array[1..2] of byte;   Data : QWord;  end;
  11.         TAlignmentTest_3 = record   _ : array[1..3] of byte;   Data : QWord;  end;
  12.         TAlignmentTest_4 = record   _ : array[1..4] of byte;   Data : QWord;  end;
  13.         TAlignmentTest_5 = record   _ : array[1..5] of byte;   Data : QWord;  end;
  14.         TAlignmentTest_6 = record   _ : array[1..6] of byte;   Data : QWord;  end;
  15.         TAlignmentTest_7 = record   _ : array[1..7] of byte;   Data : QWord;  end;
  16.         TAlignmentTest_8 = record   _ : array[1..8] of byte;   Data : QWord;  end;
  17.  
  18.  
  19. begin
  20.         WriteLn(PtrUInt(@TAlignmentTest_0(NIL^).Data));  // output: '0'
  21.         WriteLn(PtrUInt(@TAlignmentTest_1(NIL^).Data));  // output: '8'
  22.         WriteLn(PtrUInt(@TAlignmentTest_2(NIL^).Data));  // output: '8'
  23.         WriteLn(PtrUInt(@TAlignmentTest_3(NIL^).Data));  // output: '8'
  24.         WriteLn(PtrUInt(@TAlignmentTest_4(NIL^).Data));  // output: '8'
  25.         WriteLn(PtrUInt(@TAlignmentTest_5(NIL^).Data));  // output: '8'
  26.         WriteLn(PtrUInt(@TAlignmentTest_6(NIL^).Data));  // output: '8'
  27.         WriteLn(PtrUInt(@TAlignmentTest_7(NIL^).Data));  // output: '8'
  28.         WriteLn(PtrUInt(@TAlignmentTest_8(NIL^).Data));  // output: '8'
  29.         ReadLn;
  30. end.

 

TinyPortal © 2005-2018