Чтобы прояснить мой вопрос, давайте начнем с примера программы:
#include <stdio.h>
#pragma pack(push,1)
struct cc {
unsigned int a : 3;
unsigned int b : 16;
unsigned int c : 1;
unsigned int d : 1;
unsigned int e : 1;
unsigned int f : 1;
unsigned int g : 1;
unsigned int h : 1;
unsigned int i : 6;
unsigned int j : 6;
unsigned int k : 4;
unsigned int l : 15;
};
#pragma pack(pop)
struct cc c;
int main(int argc, char **argv)
{ printf("%d\n",sizeof(c));
}
Вывод «8», означающий, что 56 бит (7 байт), которые я хочу упаковать, упаковываются в 8байты, по-видимому, тратит целый байт.Любопытно, как компилятор размещает эти биты в памяти, я попытался записать конкретные значения в &c
, например:
int main (int argc, char ** argv)
{
unsigned long long int* pint = &c;
*pint = 0xFFFFFFFF;
printf("c.a = %d", c.a);
...
printf("c.l = %d", c.l);
}
Как и ожидалось, на x86_64 с использованием Visual Studio 2010 происходит следующее:
*pint = 0x00000000 000000FF :
c[0].a = 7
c[0].b = 1
c[0].c = 1
c[0].d = 1
c[0].e = 1
c[0].f = 1
c[0].g = 0
c[0].h = 0
c[0].i = 0
c[0].j = 0
c[0].k = 0
c[0].l = 0
*pint = 0x00000000 0000FF00 :
c[0].a = 0
c[0].b = 0
c[0].c = 0
c[0].d = 0
c[0].e = 0
c[0].f = 0
c[0].g = 1
c[0].h = 127
c[0].i = 0
c[0].j = 0
c[0].k = 0
c[0].l = 0
*pint = 0x00000000 00FF0000 :
c[0].a = 0
c[0].b = 0
c[0].c = 0
c[0].d = 0
c[0].e = 0
c[0].f = 0
c[0].g = 0
c[0].h = 32640
c[0].i = 0
c[0].j = 0
c[0].k = 0
c[0].l = 0
и т. Д.
На мгновение забудьте о переносимости и предположите, что вам нужен один процессор, один компилятор и одна среда выполнениясреда.Почему VC ++ не может упаковать эту структуру в 7 байтов?Это длина слова?В MSDN docs на #pragma pack
говорится, что «выравнивание элемента будет происходить по границе, кратной n [1 в моем случае] или кратной размеру элемента, в зависимости от того,меньше «.Кто-нибудь может дать мне некоторое представление о том, почему я получаю размер 8, а не 7?