I got stuck about #pragma pack(1)
wrong behavior when define a 6-bit
field and assumes it as 8-bit
. I read this question to solving my problem but it doesn't help me at all.
In Visual Studio 2012 I defined bellow struct
for saving Base64
characters :
#pragma pack(1)
struct BASE64 {
CHAR cChar1 : 6;
CHAR cChar2 : 6;
CHAR cChar3 : 6;
CHAR cChar4 : 6;
};
Now I got its size with sizeof
, but the result isn't what I expected :
printf("%d", sizeof(BASE64)); // should print 3
Result : 4
I was expect that get 3
(because 6 * 4 = 24
, so 24
bit is 3
byte)
Event I tested it with 1-bit
field instead and got correct size (1-byte) :
#pragma pack(1)
struct BASE64 {
CHAR cChar1 : 2;
CHAR cChar2 : 2;
CHAR cChar3 : 2;
CHAR cChar4 : 2;
};
Actually, why 6-bit
assumes 8-bit
with #pragma pack(1)
?
#pragma pack
generally packs on byte boundaries, not bit boundaries. It's to prevent the insertion of padding bytes between fields that you want to keep compressed. From Microsoft's documentation (since you provided the winapi
tag, and with my emphasis):
n
(optional) : Specifies the value, in bytes, to be used for packing.
How an implementation treats bit fields when you try to get them to cross a byte boundary is implementation defined. From the C11 standard (secion 6.7.2.1 Structure and union specifiers /11
, again my emphasis):
An implementation may allocate any addressable storage unit large enough to hold a bitfield. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.
More of the MS documentation calls out this specific behaviour:
Adjacent bit fields are packed into the same 1-, 2-, or 4-byte allocation unit if the integral types are the same size and if the next bit field fits into the current allocation unit without crossing the boundary imposed by the common alignment requirements of the bit fields.