4

这是一个片段:

#pragma pack(4)
struct s1
{
    char a;
    long b;
};
#pragma pack()

#pragma pack(2)
struct s2
{
    char c;
    struct s1 st1;
};
#pragma pack()


#pragma pack(2)
struct s3
{
    char a;
    long b;
};
#pragma pack()

#pragma pack(4)
struct s4
{
    char c;
    struct s3 st3;
};
#pragma pack()

我虽然 sizeof(s4) 应该是 10 或 12。但结果是 8。我使用的是 Visual C++ 6.0。有人能告诉我为什么吗?

4

4 回答 4

2
#pragma pack(2)
struct s3
{
    char a;
    long b;
};
#pragma pack()

所以包装对齐s3是2,它的大小是1(对齐1)+1(填充)+4(对齐2)=6。

#pragma pack(4)
struct s4
{
    char c;
    struct s3 st3;
};
#pragma pack()

的打包对齐s4为4,其大小为1(对齐1)+1(填充)+6(对齐2)=8。

请注意,#pragma pack这不会“额外对齐”任何具有较宽松对齐要求的东西。它只减少对齐,即控制“打包”对齐。

于 2012-11-26T05:07:26.140 回答
1

的文档#pragma pack(n)说“成员的对齐方式将在边界上,要么是 n 的倍数,要么是成员大小的倍数,以较小者为准”。但是我认为这是不正确的;文档应该说成员的对齐方式将在 n 的倍数或成员的对齐要求的边界上,以较小者为准。

的对齐要求struct s3是 2(由于#pragma pack(2)在声明时生效)。因此,即使在有效的结构中,它仍然得到 2 的对齐#pragma pack(4)。所以布局struct s4看起来像:

 char c;
 char padding;      // for alignment of the `struct s3`
 char s3.a;
 char s3.padding;   // for alignment
 long s3.b;

总大小 == 8。

于 2012-11-26T05:22:59.613 回答
0

s3, char(1) + long(4) = 5 -> 6(压缩)

s4, char(1) + struct s3(6) = 7 -> 8(压缩)

我实际上不确定如何#pragma pack工作,但这似乎是合理的。

于 2012-11-26T05:05:07.403 回答
0

这验证了 Michael Burr 所说的:

#include <stdio.h>

#pragma pack(push, 2)
struct s3
{
    long b;
};
#pragma pack(pop)

struct s4
{
    char c;
    struct s3 st3;
};

int main() {
    printf("%lu, %lu\n", sizeof(s3), sizeof(s4));
    return 0;
}

输出:4、6

于 2012-11-26T05:41:28.160 回答