Recent

Author Topic: Maintaining Alignment of records across units.  (Read 2774 times)

Laurie

  • New Member
  • *
  • Posts: 19
Maintaining Alignment of records across units.
« on: August 02, 2015, 12:09:50 pm »
Maintaining Alignment of records across units.

Help!!
I am moving a large medical notes and billing system from Delphi 7 to Lazarus in Windows but the plan is to run under Linux.

It seems that I cannot maintain consistent record sizes across units in a single project Lazarus/FPC.

Before proving a code example, I will try and explain what is happening.

The 'packed' records contain fields of known length, of strings (String[21]) and integers (4 bytes) as well as some enumerated types (one byte) that have been used for years in a number of networked installations. The records are written to and read from typed files of the same record type. In Lazarus/FPC, I have used {$A1} and {$MINENUMSIZE 1} to force field alignment and enumerated types into the smallest memory to match the storage allocation by Delphi.

The Sizeof() intrinsic reports the correct (same as Delphi) record size if used in the unit where the record is declared. According the records are read and written to the data files correctly from that unit.

BUT from any other unit, the sizeof() intrinsic reports a larger value of types and records declared in the original 'Types' unit interface.

So, procedures written in a unit that USES the original 'Types' unit that declared the records, results in incorrect access the data files.

I have types declared in one 'Types' unit and file access in another unit.

I have a main unit that defines record types like this
Unit Types;
{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}
{$H-}
{$A-}  //for Delphi32 so that the structures are the same size as the DOS and windows versions
{$IFDEF FPC}
  {$A1}   //pack on single byte boundaries for FPC/Lazarus
{$ENDIF}
{$MINENUMSIZE 1}  //So that enumerated types are same size as in Delphi
{$Z1}
Type
  Transaction = Packed record
    .....
    end;

And another unit that implements file access with the same complier directives as listed above.

QUESTION: As this works in Delphi, am I missing a project wide setting in the Lazarus IDE to maintain minimum record size across units?  I have been through all Project options but cannot find such a setting. Is there something else ? $CODEALIGN.  ??

Any help greatly appreciated.
Laurie
Lazarus 1.4.2  FPC 2.6.2  Windows 7
« Last Edit: August 02, 2015, 02:04:40 pm by Laurie »

howardpc

  • Hero Member
  • *****
  • Posts: 3205
Re: Maintaining Alignment of records across units.
« Reply #1 on: August 02, 2015, 01:52:27 pm »
FPC knows the bitpacked specifier, so records can be declared that are guaranteed to always occupy exactly the anticipated size.

Code: [Select]
type
  myExactSizeRec = bitpacked record
    field1: word;
    field2: byte;
    .. etc.
  end;

(This also allows you to declare records whose size is not an integral multiple of byte).

Leledumbo

  • Hero Member
  • *****
  • Posts: 8114
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Maintaining Alignment of records across units.
« Reply #2 on: August 02, 2015, 04:03:51 pm »
Actually, that should be impossible unless there's a mix of old & new .ppu or identifier shadowing. Prove that it really happens with the attached project (it shows 27 for all 3 calls here).

Laurie

  • New Member
  • *
  • Posts: 19
Re: Maintaining Alignment of records across units.
« Reply #3 on: August 02, 2015, 04:15:50 pm »
Solved. 
LeLedumbo you are right there was a mixture of old and new.

Thanks howardpc for the bitpacked directive, I was not aware of that.

It was a programming error and I've spent 2 days tracking it down. I'm embarrassed...there are many units involved and after checking all record fields, I discovered that a string field that I assumed was String[21] was in fact re-declared as  String[100] in a substitution include file before the record declaration.