2011-07-27 80 views
3

任何人都可以請解釋發生了什麼?MSVC 2008 16字節結構成員對齊怪異

MSVC 2008項目的結構構件對準設置被設置爲16字節(/ Zp16)對準,但是正在由16字節對準的以下結構之一和另一個由只對準8字節 ... 爲什麼?!!!

struct HashData 
{ 
    void *pData; 
    const char* pName; 
    int crc; 
    bool bModified; 
}; // sizeof (HashData) == 4 + 4 + 4 + 1 + padding = 16 bytes, ok 

class StringHash 
{ 
    HashData data[1024]; 
    int mask; 
    int size; 
}; // sizeof(StringHash) == 1024 * 16 + 4 + 4 + 0 = 16392 bytes, why not 16400 bytes? 

這可能不會看起來像一個大問題,但對我來說是很大的問題,因爲我不得不仿效MSVC結構排列在GCC並指定對齊(16)屬性使sizeof(StringHash)== 16400

請你告訴我,什麼時候,爲什麼MSVC覆蓋/Zp16設置,我絕對無法捉摸它...

回答

4

我想你是誤會了/Zp16選項。

MSDN says

當指定此選項中,第一後的各結構構件是 存儲在成員類型的規模或n字節邊界 (其中n是1,2,4 ,8或16),,以較小者爲準。

請閱讀「以較小者爲準」。它並不是說該結構將被填充16。它定義了每個成員相對於彼此的邊界,從第一個成員開始。

,你基本上要的是align (C++)屬性,它說

使用__declspec(對齊(#))來精確控制用戶定義的數據

因此,嘗試這種對齊:

_declspec(align(16)) struct StringHash 
{ 
    HashData data[1024]; 
    int mask; 
    int size; 
}; 

std::cout << sizeof(StringHash) << std::endl; 

它應該打印你所期望的。

或者您可以使用#pragma pack(16)

+1

+1此外OP,如果你想要做類似的東西'__attribute __((排列(16)))'在MSVC中它是'#pragma pack(push,16)''struct/* ... * /''#pragma pack(pop)'。 – user786653

1

考慮使用包編譯指令:

// Set packing to 16 byte alignment 
#pragma pack(16) 

struct HashData 
{ 
    void *pData; 
    const char* pName; 
    int crc; 
    bool bModified; 
}; 

class StringHash 
{ 
    HashData data[1024]; 
    int mask; 
    int size; 
}; 

// Restore default packing 
#pragma pack() 

見:packWorking with Packing Structures