记录的Ada pragma Pack或Alignment属性?

时间:2016-04-13 08:07:52

标签: ada memory-alignment

刚刚发现对齐问题我不确定哪种方法是处理它们的最佳/最安全的方法。我有一个记录,我串行通过流发送,反之亦然,所以它必须符合接口规范,不包含填充。

给出示例记录:

type MyRecord is record
a : Unsigned_8;
b : Unsigned_32;
end record;

默认情况下需要8个字节,但我可以使用2种方法删除打包:

for MyRecord'Alignment use 1;

pragma Pack (MyRecord);

我发现了一些与C示例有关的问题,但未能找到最合适的方法,如何确定使用哪种方法或它们是否相同?

更新

当我尝试使用“真实”代码而不是基本示例时,我发现Alignment属性实现了我想要的。 pragma Pack显着减小了大小,但没有确认,但我认为它已经打包了我正在使用的许多枚举类型,覆盖了应用于每种类型的'size use 8属性。

2 个答案:

答案 0 :(得分:4)

对于Streams,您可以保留MyRecord而不包含任何陈述条款,并使用默认的MyRecord’WriteMyRecord’Read; ARM 13.13.2(9)

  

对于基本类型,Read读取(和写入)Stream_Size为类型T隐含的流元素的数量;这些流元素的表示是实现定义的。对于复合类型,每个组件的Write或Read属性以规范顺序调用,这是数组最快变化的最后一个维度(除非数组的约定是Fortran,在这种情况下它是第一个维度变化最快的),以及位置记录的总订单。

GNAT实现(可能是其他实现)的一个可能的缺点是’Write’Read调用每个结束调用底层网络软件。通常情况下,这不是问题(除了可能的低效率),但如果你使用的是TCP_NODELAY(或者更糟的是UDP),那么不是你正在寻找的行为。

重载’Write会导致回到原来的问题(但至少它只限于重载过程,因此程序的其余部分可以处理正确对齐的数据)。

我为此使用了内存流(尤其是UDP的情况); ’Write到内存中的流,然后将Stream_Element_Array发送到套接字。一个例子是ColdFrame.Memory_Streams.ads.adb)。

答案 1 :(得分:1)

如果您想要完全控制,我认为您需要记录表示条款:

for MyRecord'Size use 40;
for MyRecord use record 
    a at 0 range 0 .. 7;
    b at 1 range 0 .. 31;
end record;

(或者其他一些,我可能在这里搞砸了一些指数)。

注意:根据Simon的评论进行编辑