Hi,
I have a question about field's alignment in GNU Pascal records on different platforms.
Consider the sample program below:
Program offsets; Type Rec1_t = Record Str16 : String(16); R : Real; End; Rec2_t = Record Str11 : String(11); Rec1 : Rec1_t; End; Rec3_t = Record Str11 : String(11); Str16 : String(16); R : Real; End; Var Rec1 : Rec1_t; Rec2 : Rec2_t; Rec3 : Rec3_t; Begin WriteLn('Offset of Str11 in Rec2 : ', LongInt(@Rec2.Str11) - LongInt(@Rec2)); WriteLn('Offset of Rec1 in Rec2 : ', LongInt(@Rec2.Rec1) - LongInt(@Rec2)); WriteLn('Offset of Str16 in Rec2 : ', LongInt(@Rec2.Rec1.Str16) - LongInt(@Rec2)); WriteLn('Offset of R in Rec2 : ', LongInt(@Rec2.Rec1.R) - LongInt(@Rec2)); WriteLn; WriteLn('Offset of Str11 in Rec3 : ', LongInt(@Rec3.Str11) - LongInt(@Rec3)); WriteLn('Offset of Str16 in Rec3 : ', LongInt(@Rec3.Str16) - LongInt(@Rec3)); WriteLn('Offset of R in Rec3 : ', LongInt(@Rec3.R) - LongInt(@Rec3)); End.
When compiled under X86 linux: dibm0014:/home/gnu-port/tests$ gpc --version gpc 20050331, based on gcc-3.4.5 20050821 (prerelease) (Debian 3.4.4-8) Copyright (C) 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The program produces the following results:
Offset of Str11 in Rec2 : 0 Offset of Rec1 in Rec2 : 20 Offset of Str16 in Rec2 : 20 Offset of R in Rec2 : 48
Offset of Str11 in Rec3 : 0 Offset of Str16 in Rec3 : 20 Offset of R in Rec3 : 48
This looks good to me. Rec1 and Rec3 map on each other. However when compiled under SUN Sparc Solaris 10, the same program produces this result:
<gnu-pascal> gpc --version gpc 20051116, based on gcc-3.4.4 Copyright (C) 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
<gnu-pascal> offsets Offset of Str11 in Rec2 : 0 Offset of Rec1 in Rec2 : 24 Offset of Str16 in Rec2 : 24 Offset of R in Rec2 : 56
Offset of Str11 in Rec3 : 0 Offset of Str16 in Rec3 : 20 Offset of R in Rec3 : 48
So my question is: How come the difference in alignment of Rec1 in Rec2 between Sparc and Linux? I know that Real data is aligned on 8 bytes boundaries on Sparc platforms but why is the address of Rec1 aligned on 8 bytes instead of 4? So the two records (Rec2 and Rec3) containing the same data are of different sizes and do not map anymore. This causes some trouble in my programs since this kind of data structures are passed back and forth to C code, in order to interface with a database engine. This difference does not happen if there is no Real in the sub-structure.
I can manage this with 'dummy' fields in record declarations - enclosed in {$ifdef }...{$endif} but I would like to be sure to understand how the alignment is done in order to avoid recurrent problems on this matter.
Kind regards
Pascal Viandier