Pascal 记录在记录中混合字和字节不能按预期工作
Pascal records mixing word and bytes in records doesn't work as expected
我的数据是这样的(一个字节每两个'-'):
+----+--+----+----+
|0840|0C|00AD|0840|
+----+--+----+----+
如果我使用此代码:错误
Type TAlarmasRATP = record
Funcion : word;
Instancia : byte;
Err_0 : word;
Err_1 : word;
end;
函数 = 4008,Instancia = 0C,Err_0 = 08AD,Err_1 = 0040
如果我使用此代码:RIGHT
Type TAlarmasRATP = record
Funcion : word;
Instancia : byte;
Err_0 : array [0..1] of byte;
Err_1 : array [0..1] of byte;
end;
函数 = 4008,Instancia = 0C,Err_0 = AD00,Err_1 = 4008
为什么第一个不起作用?
使用记录类型时,字段根据规范对齐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
这意味着:在第一个记录声明中,Err_0
字段将在 Word
边界上对齐,并且会在 Instancia
字段后附加一个填充字节。
在第二个记录声明中,Err_0
字段将在 Byte
边界上对齐,因为它是 Byte
的数组,并且 [= 之后没有填充27=] 字段。由于记录未打包,因此将在结构末尾插入一个填充字节 - 因此在两种情况下记录大小都将四舍五入为 8。
如果您使用 packed
关键字,记录中的所有字段将被打包到字节边界,并且记录的大小将恰好是字段大小的总和,末尾没有填充。
如果记录大小为 7,您只需声明:
type TAlarmasRATP = packed record
Funcion : Word;
Instancia : Byte;
Err_0 : Word;
Err_1 : Word;
end;
但是,如果您需要 8 的大小,您应该通过定义另一个您从不使用的字段来在末尾手动添加一个填充字节:
type TAlarmasRATP = packed record
Funcion : Word;
Instancia : Byte;
Err_0 : Word;
Err_1 : Word;
Padding : Byte; // Unused
end;
我的数据是这样的(一个字节每两个'-'):
+----+--+----+----+
|0840|0C|00AD|0840|
+----+--+----+----+
如果我使用此代码:错误
Type TAlarmasRATP = record
Funcion : word;
Instancia : byte;
Err_0 : word;
Err_1 : word;
end;
函数 = 4008,Instancia = 0C,Err_0 = 08AD,Err_1 = 0040
如果我使用此代码:RIGHT
Type TAlarmasRATP = record
Funcion : word;
Instancia : byte;
Err_0 : array [0..1] of byte;
Err_1 : array [0..1] of byte;
end;
函数 = 4008,Instancia = 0C,Err_0 = AD00,Err_1 = 4008
为什么第一个不起作用?
使用记录类型时,字段根据规范对齐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 |
这意味着:在第一个记录声明中,Err_0
字段将在 Word
边界上对齐,并且会在 Instancia
字段后附加一个填充字节。
在第二个记录声明中,Err_0
字段将在 Byte
边界上对齐,因为它是 Byte
的数组,并且 [= 之后没有填充27=] 字段。由于记录未打包,因此将在结构末尾插入一个填充字节 - 因此在两种情况下记录大小都将四舍五入为 8。
如果您使用 packed
关键字,记录中的所有字段将被打包到字节边界,并且记录的大小将恰好是字段大小的总和,末尾没有填充。
如果记录大小为 7,您只需声明:
type TAlarmasRATP = packed record
Funcion : Word;
Instancia : Byte;
Err_0 : Word;
Err_1 : Word;
end;
但是,如果您需要 8 的大小,您应该通过定义另一个您从不使用的字段来在末尾手动添加一个填充字节:
type TAlarmasRATP = packed record
Funcion : Word;
Instancia : Byte;
Err_0 : Word;
Err_1 : Word;
Padding : Byte; // Unused
end;