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機)。