4
struct tag_t_ {
    u_int8_t op;
    u_int8_t num;
    u_int32_t labels[5];
};

在上面的结构中,64 位编译器会在哪里添加填充字节?
它是在第一个标签之前还是在第一个标签的末尾?
如果填充位于第一个标签的末尾,在访问(读取)32 位拱门中的第一个标签时会导致任何错误结果吗?

4

3 回答 3

4

这取决于编译器,没有可以应用并保证成立的通用规则。

我不确定问题的后半部分,因为在 32 位架构上,编译器当然会有所不同。直接转移结构从来都不是一个好主意。

因为填充的原因,如果你sizeof (tag_t_)在 64 位机器上向某些外部媒体写入字节,传输媒体,然后sizeof (tag_t_)在 32 位机器上尝试读取,就会失败。所以不要那样做。逐个字段序列化结构,并以相同的方式反序列化它们。

于 2012-11-07T06:26:57.227 回答
4

我在 64 位系统中运行它——结构的内存映射是

offset:  variable
     0:  op num     
     2:  00 00   // only 2 paddings
     4:  label0
     8:  label1
         ...
    20:  label5

大小(结构)== 24

// 这里可以在字符和第一个 32 位整数之间放置一个无符号短整数,而不会影响结构的大小。

结构填充的规则是宽度为 W 的任何基本变量都将与该宽度对齐。双倍作为第二个参数将导致 7 个填充字节之后op,并且只有 3 个填充字节之后num,因为标签 [0] 然后将从可被 4 整除的偏移量开始。

32/64 位系统之间存在差异:32 位系统仍会将 8 字节变量与 32 位边界对齐。64 位系统会将 long int 和 double 对齐到 8 字节边界。

这将使在 32 位系统中使用该结构变得安全。如果结构中有双精度数,仍然可以使结构与变量的仔细规划兼容。

于 2012-11-07T06:27:00.520 回答
0

填充通常应用在每个字段的末尾。不,64 位编译的二进制文件与 32 位二进制文​​件不兼容。因此,您可能必须为 32 位架构重新编译所有内容。

然后对齐将由 32 位编译器进行处理,并相应地生成地址。

于 2012-11-07T06:26:21.863 回答