I use Visual Studio 2013 for a x64 system. I have the following struct:
#pragma pack(1)
struct TimeStruct
{
int milliseconds : 10;
BYTE seconds : 6;
BYTE minutes : 6;
BYTE hour : 5;
BYTE day : 5;
};
#pragma pack()
and an array:
TimeStruct stArray[10];
When I use sizeof(stArray);
I get 80 as a resault instead of 40.
I need to know if the problem is that the compiler doesn't pack correctly or if sizeof doesn't consider the bitfield's actual size.
Thanks
See What is VC++ doing when packing bitfields? for more explanation on how MSVC treats bitfields.
It's implementation dependent how bitfields are packed and ordered, so be aware that the layout can be different from what you expect, and will depend on the particular compiler you are using.
sizeof() gives you the size of the struct regardless of what its members are, so it's the bitfield packing that's different from your expectations.
You can possibly rason about the layout from the documentation or use this code to empirically discover the layout:
struct TimeStruct a;
unsigned char *b = (unsigned char*)&a;
a.milliseconds = 1;
a.seconds = 2;
a.minutes = 3;
a.hour = 3;
a.day = 4;
for(size_t i = 0; i < sizeof a; i++)
printf("%02X ", b[i]);
-> 64 bit compiler 01 00 00 00 02 03 04 05
-> 32 bit compiler 01 30 FE 00 02 03 A4 65
It appears the struct is allocated an entire int for the 1. int milliseconds : 10;
member, and the remaining 3 bytes are packed individually after that, allocating a BYTE for each member, but not combining bits from the different allocated units.
You should be able to pack it tightly with the MSVC compiler if you use int or unsigned int for all the fields, and this struct will take 4 bytes:
struct TimeStruct
{
int milliseconds : 10;
int seconds : 6;
int minutes : 6;
int hour : 5;
int day : 5;
};