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((a)Rec2.Str11) -
LongInt(@Rec2));
WriteLn('Offset of Rec1 in Rec2 : ', LongInt((a)Rec2.Rec1) -
LongInt(@Rec2));
WriteLn('Offset of Str16 in Rec2 : ', LongInt((a)Rec2.Rec1.Str16) -
LongInt(@Rec2));
WriteLn('Offset of R in Rec2 : ', LongInt((a)Rec2.Rec1.R) -
LongInt(@Rec2));
WriteLn;
WriteLn('Offset of Str11 in Rec3 : ', LongInt((a)Rec3.Str11) -
LongInt(@Rec3));
WriteLn('Offset of Str16 in Rec3 : ', LongInt((a)Rec3.Str16) -
LongInt(@Rec3));
WriteLn('Offset of R in Rec3 : ', LongInt((a)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