Hello,
After noticing that gdb does not print 64 bit fields of (bit)packed records properly if they don't start on a byte boundary (both with fpc and with gpc), I decided to check what gcc does. It turns out that gcc (4.0.1, Mac OS X/ppc) only bitpacks values up to and including 59 bits. Fields declared as 60-64 bits are automatically aligned to the target-specific alignment boundary.
Does anyone here know why this is the case, and possibly where this is documented? I can't find anything with Google.
Thanks,
Jonas
Simple test case follows (compile with -c -gdwarf-2, then use dwarfdump/elfread --debug-dump on the .o file to look at the debug info). both l and l2 are aligned on an 8 byte boundary for ppc64 and to a 4 byte boundary for ppc32.
*** struct tt { int a; int j; };
struct S { int j:5; long long l:60; long long l2:60; int k:6; int m:5; int n:8; struct tt s; };
int main(struct S s) { } ***
Compare with a Pascal program:
*** {$ifdef fpc} {$bitpacking on} {$endif}
type {$ifndef fpc} int64 = longint; {$endif} tenum = (ea,eb,ec,ed,ee,ef,eg,eh); tr = packed record a: 0..3; // 2 bits i: int64; c: boolean; // 1 bit d: 0..31; // 5 bits e: tenum; // 3 bits end;
procedure t(var r2: tr); var r: tr; begin r.a := 2; r.i := 1234567890123456789; r.c := true; r.d := 5; r.e := ed; r2 := r; end;
var r: tr;
begin t(r); if (r.a <> 2) or (r.i <> 1234567890123456789) or (not r.c) or (r.d <> 5) or (r.e <> ed) then halt(1); end. ***
If you debug this, step over the "t" call and print r, you get (for gpc):
(gdb) p r $1 = { A = 2, I = 0, C = true, D = 5, E = Ed } (gdb) ptype r type = record A : 0..3 : 2; I : Int64 : 64; C : Boolean : 1; D : 0..31 : 5; E : Tenum : 3; end
Looking at the stabs (the gpc for Mac OS X I have doesn't support dwarf), gpc also puts the 64 bit int right after the two first bits, without aligning to a byte/4 byte/8 byte boundary first.