MSVC 2008 Странность выравнивания элементов структуры 16 байтов - PullRequest
3 голосов
/ 27 июля 2011

Кто-нибудь может объяснить, что происходит?

Мой 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 , я абсолютно не могу ее понять ...

Ответы [ 2 ]

4 голосов
/ 27 июля 2011

Я думаю, вы неправильно поняли вариант /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) .

1 голос
/ 27 июля 2011

Рассмотрите возможность использования директивы 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()

См .: упаковка и Работа с упаковочными конструкциями

...