2

我试图通过使用#pragma pack (n)来调整数据成员。采取以下为例:#pragma pack(16)和#pragma pack(8)的效果总是一样吗?

#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      | 

但我不明白为什么结果还是24n=16。我也尝试了其他的例子,他们似乎都给出了相同的结果n=8n=16。有人能解释为什么吗?数据成员是否与n=8相同?

附注:在Win-x64下测试VS2010。

回答

5

从你的网页链接到:

成员的排列将是一个边界要么是n的 多或部件的大小,取其 较小的倍数上。

对于每个成员,其成员的最优对齐和包值之间的最小对齐。在你的榜样成员对齐完全一样的,不管pack(8)pack(16)因为类型的最优比均小于16

如果有,需要16字节对齐的成员,如__m128,你会能够找到不同的结果。

+0

谢谢。现在有道理。我在哪里可以找到*的参考?对于每个成员,它需要最小对齐,在成员的最佳对齐和包装值之间。 – herohuyongtao

+1

'pragma pack'是一个编译器扩展。恐怕唯一的参考将是你链接到的页面。我引用的部分基本上是这样说的。 –

2

因为pack指定了需要时使用的最大对齐方式。小于16字节的值仍然会与较小的值对齐,因为在将它们对齐到较大的值时没有增益。所以一个32位的整数仍然对齐到4个字节。双精度对齐到8个字节。所以当你在4和8之间切换时,你可能会看到不同。

3

对于pack意思是很多,所涉及的结构必须包含一个至少与指定到编译指示的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机)。