Ответ 1
Реализация определена как поля будут помещаться в структуру. Visual Studio поместит последовательные битовые поля в базовый тип, если это возможно, и потеряет оставшееся пространство. (Поля бит С++ в VS)
У меня есть структура битовых полей, которые содержат до 48 бит. В GCC это правильно приводит к 6-байтовой структуре, но в MSVC структура выходит из 8 байтов. Мне нужно найти способ заставить MSVC правильно упаковать структуру, как для интероперабельности, так и потому, что она используется в критически важной для среды среде.
Структура, представленная ниже, состоит из трех 15-битных чисел, одного 2-битного числа и 1-битного знака. 15 + 15 + 15 + 2 + 1 = 48, поэтому теоретически он должен входить в шесть байтов, верно?
struct S
{
unsigned short a:15;
unsigned short b:15;
unsigned short c:15;
unsigned short d:2;
unsigned short e:1;
};
Однако, компиляция этого как на GCC, так и на MSVC приводит к sizeof(S) == 8
. Думая, что это может иметь отношение к выравниванию, я попытался использовать #pragma pack(1)
перед объявлением структуры, сообщая компилятору о возврате в байты, а не int, границы. В GCC это сработало, в результате получилось sizeof(S) == 6
.
Однако на MSVC05 размерof все равно вышел на 8, даже с pack(1)
установлен! Прочитав этот другой ответ SO, я попытался заменить unsigned short d
на unsigned char
и unsigned short e
на bool
. Результат: sizeof(S)
== 7!
Я обнаружил, что если я разделил d на два однобитовых поля и вклинил их между другими членами, структура, наконец, упакована должным образом.
struct S
{
unsigned short a:15;
unsigned short dHi : 1;
unsigned short b:15;
unsigned short dLo : 1;
unsigned short c:15;
unsigned short e:1;
};
printf( "%d\n", sizeof(S) ); // "6"
Но с тем, что я так раскололся, это громоздко и вызывает проблемы для меня позже, когда я должен работать над структурой. Есть ли способ заставить MSVC упаковать эту структуру в 6 байтов, точно так же, как GCC?
Реализация определена как поля будут помещаться в структуру. Visual Studio поместит последовательные битовые поля в базовый тип, если это возможно, и потеряет оставшееся пространство. (Поля бит С++ в VS)
Если вы используете тип unsigned __int64 для объявления всех элементов структуры, вы получите объект с sizeof (S) = 8, но последние два байта не будут использоваться, а первые шесть будут содержать данные в нужном формате.
В качестве альтернативы, если вы можете принять некоторое переупорядочение структуры, это будет работать
#pragma pack(1)
struct S3
{
unsigned int a:15;
unsigned int b:15;
unsigned int d:2;
unsigned short c:15;
unsigned short e:1;
};
Я так не думаю, и я считаю, что поведение MSVC на самом деле правильное, и GCC, который отклоняется от стандарта.
AFAIK, стандарт не позволяет битовым полям пересекать границы слова базового типа.