From 088781a22dd22f14a4f93f478dbbfc7f0eea1102 Mon Sep 17 00:00:00 2001 From: michael Date: Thu, 1 Oct 1998 08:15:11 +0000 Subject: [PATCH] + Update on packrecords --- docs/prog.tex | 16 +++---- docs/ref.tex | 114 ++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 111 insertions(+), 19 deletions(-) diff --git a/docs/prog.tex b/docs/prog.tex index 7766462521..66c52ba53f 100644 --- a/docs/prog.tex +++ b/docs/prog.tex @@ -631,18 +631,20 @@ object or class type definition. It is of the following form: \begin{verbatim} -{$PACKRECORDS xx} +{$PACKRECORDS n} \end{verbatim} -Where \var{xxx} is one of 1,2,4,16 or \var{NORMAL} or \var{DEFAULT}. -This means that the elements of a record will be aligned on 1,2, 4 or -16 byte boundaries. Thus, the size of a record will always be a multiple of -the alignment size. +Where \var{n} is one of 1,2,4,16 or \var{NORMAL} or \var{DEFAULT}. +This means that the elements of a record that have size greater than \var{n} +will be aligned on \var{n} byte boundaries. Elements with size less than or +equal to \var{n} will be aligned to a natural boundary, i.e. to a power of +two that is equal to or larger than the element's size. + The default alignment (which can be selected with \var{DEFAULT}) is 2, contrary to Turbo Pascal, where it is 1. -More information of this can be found in the reference guide, in the section -about record types. +More information on this and an exmple program can be found in the reference +guide, in the section about record types. {\em Remark:} Sets are always put in 32 bit or 32 bytes, this cannot be changed diff --git a/docs/ref.tex b/docs/ref.tex index fb817b79a7..d0cf71b17a 100644 --- a/docs/ref.tex +++ b/docs/ref.tex @@ -955,20 +955,25 @@ The reason for this is that by default, elements of a record are aligned at 2-byte boundaries, for performance reasons. This default behaviour can be changed with the \var{\{\$PackRecords n\}} switch. Possible values for \var{n} are 1, 2, 4, 16 or \var{Default}. + This switch tells the compiler to align elements of a record or object or -class on 1,2,4 or 16 byte boundaries. The keyword \var{Default} selects the -default value for the platform you're working on (currently 2 on all -platforms) +class that have size larger than \var{n} on \var{n} byte boundaries. +Elements that have size smaller or equal than \var{n} are aligned on +natural boundaries, i.e. to the first power of two that is larger than or +equal to the size of the record element. + +The keyword \var{Default} selects the default value for the platform +you're working on (currently, this is 2 on all platforms) Take a look at the following program: \begin{listing} Program PackRecordsDemo; -type {$PackRecords 2} +type + {$PackRecords 2} Trec1 = Record A : byte; B : Word; - end; {$PackRecords 1} @@ -977,19 +982,104 @@ type {$PackRecords 2} B : Word; end; + {$PackRecords 2} + Trec3 = Record + A,B : byte; + end; + + {$PackRecords 1} + Trec4 = Record + A,B : Byte; + end; + + {$PackRecords 4} + Trec5 = Record + A : Byte; + B : Array[1..3] of byte; + C : byte; + end; + + {$PackRecords 8} + Trec6 = Record + A : Byte; + B : Array[1..3] of byte; + C : byte; + end; + + {$PackRecords 4} + Trec7 = Record + A : Byte; + B : Array[1..7] of byte; + C : byte; + end; + + {$PackRecords 8} + Trec8 = Record + A : Byte; + B : Array[1..7] of byte; + C : byte; + end; + +Var rec1 : Trec1; + rec2 : Trec2; + rec3 : TRec3; + rec4 : TRec4; + rec5 : Trec5; + rec6 : TRec6; + rec7 : TRec7; + rec8 : TRec8; + begin - WriteLn ('Size Trec1 : ',SizeOf(Trec1)); - WriteLn ('Size Trec2 : ',SizeOf(Trec2)); + Write ('Size Trec1 : ',SizeOf(Trec1)); + Writeln (' Offset B : ',Longint(@rec1.B)-Longint(@rec1)); + Write ('Size Trec2 : ',SizeOf(Trec2)); + Writeln (' Offset B : ',Longint(@rec2.B)-Longint(@rec2)); + Write ('Size Trec3 : ',SizeOf(Trec3)); + Writeln (' Offset B : ',Longint(@rec3.B)-Longint(@rec3)); + Write ('Size Trec4 : ',SizeOf(Trec4)); + Writeln (' Offset B : ',Longint(@rec4.B)-Longint(@rec4)); + Write ('Size Trec5 : ',SizeOf(Trec5)); + Writeln (' Offset B : ',Longint(@rec5.B)-Longint(@rec5), + ' Offset C : ',Longint(@rec5.C)-Longint(@rec5)); + Write ('Size Trec6 : ',SizeOf(Trec6)); + Writeln (' Offset B : ',Longint(@rec6.B)-Longint(@rec6), + ' Offset C : ',Longint(@rec6.C)-Longint(@rec6)); + Write ('Size Trec7 : ',SizeOf(Trec7)); + Writeln (' Offset B : ',Longint(@rec7.B)-Longint(@rec7), + ' Offset C : ',Longint(@rec7.C)-Longint(@rec7)); + Write ('Size Trec8 : ',SizeOf(Trec8)); + Writeln (' Offset B : ',Longint(@rec8.B)-Longint(@rec8), + ' Offset C : ',Longint(@rec8.C)-Longint(@rec8)); end. \end{listing} The output of this program will be : \begin{listing} -Size Trec1 : 4 -Size Trec2 : 3 +Size Trec1 : 4 Offset B : 2 +Size Trec2 : 3 Offset B : 1 +Size Trec3 : 2 Offset B : 1 +Size Trec4 : 2 Offset B : 1 +Size Trec5 : 8 Offset B : 4 Offset C : 7 +Size Trec6 : 8 Offset B : 4 Offset C : 7 +Size Trec7 : 12 Offset B : 4 Offset C : 11 +Size Trec8 : 16 Offset B : 8 Offset C : 15 \end{listing} -And this is as expected. In \var{Trec1}, each of the elements \var{A} and -\var{B} takes 2 bytes of memory, and in \var{Trec1}, \var{A} takes only 1 -byte of memory. +And this is as expected. In \var{Trec1}, since \var{B} has size 2, it is +aligned on a 2 byte boundary, thus leaving an empty byte between \var{A} +and \var{B}, and making the total size 4. In \var{Trec2}, \var{B} is aligned +on a 1-byte boundary, right after \var{A}, hence, the total size of the +record is 3. + +For \var{Trec3}, the sizes of \var{A,B} are 1, and hence they are aligned on 1 +byte boundaries. The same is true for \var{Trec4}. + +For \var{Trec5}, since the size of B -- 3 -- is smaller than 4, \var{B} will +be on a 4-byte boundary, as this is the first power of two that is +larger than it's size. The same holds for \var{Trec6}. + +For \var{Trec7}, \var{B} is aligned on a 4 byte boundary, since it's size -- +7 -- is larger than 4. However, in \var{Trec8}, it is aligned on a 8-byte +boundary, since 8 is the first power of two that is greater than 7, thus +making the total size of the record 16. As from version 0.9.3, \fpc supports also the 'packed record', this is a record where all the elements are byte-aligned.