我正在尝试使用#pragma pack (n)
对齐数据成员。以下面的例子为例:
#include <iostream>
using namespace std;
#pragma pack(8) // or (16)
struct A
{
int a;
char b;
char c;
char d;
char e;
char f;
double g;
};
int main()
{
cout << sizeof(A) << endl;
return 0;
}
两者都会为24
和#pragma pack(8)
打印#pragma pack(16)
。根据我的理解,我可以理解n=8
数据对齐的结果,如下所示:
Bytes: |1 2 3 4|5|6|7|8|9|10 11 12 13 14 15 16|17 18 19 20 21 22 23 24|
Data: |a |b|c|d|e|f|padding |g |
但我无法理解为什么24
的结果仍为n=16
。我还尝试了其他示例,所有这些示例似乎都为n=8
和n=16
提供了相同的结果。有人可以解释原因吗?数据成员是否与n=8
对齐?
P.S。:在Win-x64下在VS2010中测试。
答案 0 :(得分:5)
从您关联的页面:
成员的对齐将位于a的边界上 n的倍数或成员大小的倍数,以两者为准 小。
对于每个成员,它在成员的最佳对齐和包值之间采用最小对齐。无论pack(8)
和pack(16)
如何,示例中的成员都完全相同,因为类型的最佳对齐方式都小于16。
如果您的成员需要16字节对齐,例如__m128
,您将能够找到不同的结果。
答案 1 :(得分:3)
对于pack
意义重大,所讨论的结构必须包含一个至少与您为该pragma指定的N
一样大的成员。例如:
#include <iostream>
using namespace std;
#pragma pack(push)
#pragma pack(1)
struct A
{
char a;
double b;
};
#pragma pack(8)
struct B
{
char a;
double b;
};
#pragma pack(pop)
int main()
{
cout << sizeof(A) << "\n" << sizeof(B) << endl;
return 0;
}
在我的电脑上打印:
9
16
...我认为这是相当典型的(至少对于首先接受pragma pack
的机器而言)。
答案 2 :(得分:2)
因为pack指定了在需要时使用的最大对齐方式。小于16个字节的值仍将与较小的值对齐,因为将它们与较大的值对齐没有任何增益。因此,32位整数仍然与4个字节对齐。双精度对齐为8个字节。因此,当您在4到8之间切换时,您可能会看到差异。