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, а при указании атрибута align (16) sizeof (StringHash) == 16400!

Скажите, пожалуйста, когда и почему MSVC переопределяет параметр / Zp16, я абсолютно не могу это понять...

2 ответа

Решение

Я думаю, что вы неправильно поняли /Zp16 вариант.

MSDN говорит,

Когда вы указываете эту опцию, каждый элемент структуры после первого сохраняется либо с размером типа элемента, либо с n-байтовыми границами (где n равно 1, 2, 4, 8 или 16), в зависимости от того, что меньше.

Пожалуйста, прочитайте "что меньше". Это не говорит о том, что структура будет дополнена 16, Он скорее определяет границу каждого члена относительно друг друга, начиная с первого члена.

То, что вы в основном хотите, это атрибут align (C++), который говорит

Используйте __declspec(align(#)) для точного управления выравниванием пользовательских данных

Так что попробуйте это:

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

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

Он должен напечатать то, что вы ожидаете.

Или вы можете использовать #pragma pack (16).

Подумайте об использовании директивы pack pragma:

// 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()

Смотрите: упаковка и Работа со структурами упаковки

Другие вопросы по тегам