Search code examples
c++visual-c++gccalignment

MSVC 2008 16 Bytes structure members alignment weirdness


Can anybody please explain what's going on?

My MSVC 2008 project's structure member alignment setting is set to 16 bytes (/Zp16) alignment, however one of the following structures is being aligned by 16 bytes and another is aligned only by 8 bytes... WHY?!!!

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?

This may not look like a big deal, but it's a big problem for me, since I am forced to emulate the MSVC structures alignment in GCC and specifying the aligned(16) attribute makes the sizeof (StringHash) == 16400!

Please tell me, when and why MSVC overrides the /Zp16 setting, I absolutely can't fathom it...


Solution

  • I think you misunderstood the /Zp16 option.

    MSDN says,

    When you specify this option, each structure member after the first is stored on either the size of the member type or n-byte boundaries (where n is 1, 2, 4, 8, or 16), whichever is smaller.

    Please read the "whichever is smaller". It doesn't say that the struct will be padded by 16. It rather defines the boundary of each member relative to each other, starting from the first member.

    What you basically want is align (C++) attribute, which says

    Use __declspec(align(#)) to precisely control the alignment of user-defined data

    So try this:

    _declspec(align(16)) struct StringHash
    {
        HashData data[1024];
        int mask;
        int size;
    }; 
    
    std::cout << sizeof(StringHash) << std::endl;
    

    It should print what you expect.

    Or you can use #pragma pack(16).