Почему структура, состоящая из char, short и char (в таком порядке), при компиляции в C ++ с включенной 4-байтовой упаковкой приходит к 6-байтовой структуре? - PullRequest
4 голосов
/ 03 сентября 2010

Мне показалось, что я понял, как C / C ++ обрабатывает выравнивание членов структуры.Но я получаю странные результаты для определенного расположения в Visual Studio 2008 и 2010.

В частности, я обнаружил, что структура, состоящая из char, short и char, скомпилирована в 6-байтовую структурудаже при включенной 4- или 8-байтовой упаковке.Я в недоумении, почему это так.Я могу понять 4-байтовую структуру.Я мог бы понять 8-байтовую структуру.Но я бы подумал, что 6-байтовая структура была бы невозможна, если включена 4-байтовая упаковка.

Программа, которая демонстрирует проблему:

#include <iostream>
using namespace std;

#pragma pack (4)

struct Alignment
{
 char c1;
 short s;
 char c2;
};

#define REPORT_VAR_POSITION( structName, varName ) cout << "Member '" << #varName << "' sits at byte # " << offsetof( structName, varName ) << "." << endl;

int main(int argc, char* argv[])
{
 cout << "Sizeof struct Alignment is " << sizeof( Alignment ) << " bytes." << endl;
 REPORT_VAR_POSITION( Alignment, c1 );
 REPORT_VAR_POSITION( Alignment, s );
 REPORT_VAR_POSITION( Alignment, c2 );

 system( "pause" );

 return 0;
}

Вывод:

Sizeof struct Alignment is 6 bytes.
Member 'c1' sits at byte # 0.
Member 's' sits at byte # 2.
Member 'c2' sits at byte # 4.
Press any key to continue . . .

Может кто-нибудь объяснить, почему VC дополняет каждый из этих символов дополнительным байтом?

Ответы [ 3 ]

16 голосов
/ 03 сентября 2010

С документация MSDN для #pragma pack (где n - заданное вами значение):

Выравнивание элемента будет на границе, кратной n или кратной размеру элемента, в зависимости от того, что меньше.

sizeof(short) - это два байта, что меньше значения упаковки четырех байтов, которые вы установили, поэтому элемент short выровнен по двухбайтовой границе.

Последний char (c2) дополняется дополнительным байтом после него, поэтому при размещении объектов Alignment в массиве элемент short по-прежнему корректно выравнивается на двухбайтовой границе. Элементы массива являются смежными, и между ними не может быть заполнения, поэтому для обеспечения правильного выравнивания в массивах необходимо добавить заполнение к концу структуры.

4 голосов
/ 03 сентября 2010

Видимо, вы действительно неправильно это поняли.В Visual Studio вы не можете увеличить требования выравнивания для элементов структуры любого типа, используя параметры упаковки структуры.Вы можете только уменьшить их.

Если ваша структура состоит из char (выровненных по границе 1 байта) и short (выровненных по границе 2 байта) объектов, то используйте 4-и 8-байтовые параметры упаковки не окажут абсолютно никакого влияния на макет или размер вашей структуры.Результат будет точно таким же, как при 2-байтовой упаковке.Структура будет иметь размер 6 байт.

Единственная настройка упаковки, которая будет иметь какое-либо влияние в этом случае, - это 1-байтовая настройка упаковки, которая уменьшит требование выравнивания short от2 к 1 и приводят к 4-байтовому размеру структуры.

0 голосов
/ 03 сентября 2010

Компилятор Visual Studio C с этой опцией команды / Zp [n], где структура упакована на границе n , это место, где появляется директива #pragma pack, члены структуры выровнены по границе, кратной n.

...