Was macht VC ++ beim Packen von Bitfeldern?
Um meine Frage zu klären, beginnen wir mit einem Beispielprogramm:
#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));
}
Die Ausgabe ist "8", was bedeutet, dass die 56 Bits (7 Bytes), die ich packen möchte, in 8 Bytes gepackt werden und anscheinend ein ganzes Byte verschwenden. Ich war neugierig, wie der Compiler diese Bits im Speicher anordnete, und habe versucht, bestimmte Werte in @ zu schreibe&c
, z.B.
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);
}
Vorhersehbar geschieht unter x86_64 mit Visual Studio 2010 Folgendes:
*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
etc
Vergessen Sie für einen Moment die Portabilität und gehen Sie davon aus, dass Sie sich um eine CPU, einen Compiler und eine Laufzeitumgebung kümmern. Warum kann VC ++ diese Struktur nicht in 7 Bytes packen? Ist es eine wortlange Sache? DasMSDN docs auf#pragma pack
sagt: "Die Ausrichtung eines Elements befindet sich an einer Grenze, die entweder ein Vielfaches von n [1 in meinem Fall] oder ein Vielfaches der Größe des Elements ist, je nachdem, welcher Wert kleiner ist." Kann mir jemand eine Vorstellung davon geben, warum ich eine Größe von 8 und nicht von 7 bekomme?