My data is like this (one byte each two '-'):
+----+--+----+----+
|0840|0C|00AD|0840|
+----+--+----+----+
If I use this code: WRONG
Type TAlarmasRATP = record
Funcion : word;
Instancia : byte;
Err_0 : word;
Err_1 : word;
end;
Funcion = 4008, Instancia = 0C, Err_0 = 08AD, Err_1 = 0040
If I use this code: RIGHT
Type TAlarmasRATP = record
Funcion : word;
Instancia : byte;
Err_0 : array [0..1] of byte;
Err_1 : array [0..1] of byte;
end;
Funcion = 4008, Instancia = 0C, Err_0 = AD00, Err_1 = 4008
Why the first one is not working?
When a record type is used, fields are aligned according to the specification Internal data formats - Record types:
type | alignment in bytes (32bit platform) |
---|---|
ordinal | size of the type (i.e. 1 for Byte , 2 for Word , 4 for Cardinal , or 8 for Int64 ) |
real | 2 for Real48 , 4 for Single , 8 for Double and Extended |
ShortString |
1 |
Array |
Same as the element type of the array |
Record |
The largest alignment of the fields in the record |
Set |
Size of the type (1, 2, or 4), otherwise always 1 |
all other | Determined by the {$A} directive |
That means: in the first record declaration the Err_0
field will be aligned on a Word
boundary and that will append one padding byte after the Instancia
field.
In the second record declaration the Err_0
field will be aligned on a Byte
boundary, because it is an array of Byte
and there will be no padding after the Instancia
field. Since the record is not packed, a padding byte will be inserted at the end of the structure - so the record sizes will be rounded to 8 in both cases.
If you use the packed
keyword all fields in the record will be packed to the byte boundary and the size of the record will be exactly the sum of the field sizes, with no padding at the end.
For having a record size of 7 you can simply declare:
type TAlarmasRATP = packed record
Funcion : Word;
Instancia : Byte;
Err_0 : Word;
Err_1 : Word;
end;
However, if you need a size of 8 you should manually add a padding byte at the end by defining just another field that you never use:
type TAlarmasRATP = packed record
Funcion : Word;
Instancia : Byte;
Err_0 : Word;
Err_1 : Word;
Padding : Byte; // Unused
end;