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
вариант.
Когда вы указываете эту опцию, каждый элемент структуры после первого сохраняется либо с размером типа элемента, либо с 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()
Смотрите: упаковка и Работа со структурами упаковки