If you really want to know what's happening, you need to look at the level below C. For example, the following program will tell you how big the total structure is, as well as the BYTE
fields:
#include <stdio.h>
typedef unsigned char BYTE;
typedef unsigned int UINT;
#pragma pack(push, 1)
typedef struct {
BYTE mValue1; BYTE mValue2;
UINT mValue3:5; UINT mValue4:11;
} MyPackedStruct;
MyPackedStruct x;
#pragma pack( pop )
int main (void) {
printf ("%zd\n", sizeof(x));
printf ("%zd\n", sizeof(x.mValue1));
return 0;
}
Unfortunately, you can't get the size of a bit field in the same way so, to get that, you'd need to go down to the assembly level, with something like:
#include <stdio.h>
typedef unsigned char BYTE;
typedef unsigned int UINT;
#pragma pack(push, 1)
typedef struct {
BYTE mValue1; BYTE mValue2;
UINT mValue3:5; UINT mValue4:11;
} MyPackedStruct;
MyPackedStruct x;
#pragma pack( pop )
int main (void) {
x.mValue3 = 21; // 10101
x.mValue4 = 1198; // 10010101110
return 0;
}
The basic idea would be to turn that into assembly and then examine the code to see how it sets the values. That will let you know how they're structured under the covers. For example, under my gcc
environment, it loads the individual bits into eax
but only uses the lower 8 bits in al
, and it comes out:
movzbl _x+2, %eax
andl $-32, %eax ;; -32 = 111_00000, clears lower 5 bits
orl $21, %eax ;; then store 21 (10101) into those bits
movb %al, _x+2 ;; hence val3 uses lower 5 bits of third byte
movzbl _x+2, %eax
andl $31, %eax ;; 31 = 000_11111, clear all upper bits
orl $-64, %eax ;; -64 = 110_00000, 110 is the (lower of 1198)
movb %al, _x+2
movzbl _x+3, %eax
andl $0, %eax ;; clear all bits
orl $-107, %eax ;; stores 10010101 into fourth byte (upper of 1198)
movb %al, _x+3 ;; so val4 uses all fourth byte and 3 bits of third
So, in this particular case, the full size is 32 bits, allocated thus:
--- increasing memory addresses -->
11111111 22222222 55533333 44444444
\______/ \______/ \_/\___/ \______/
value1 value2 | value3 | value4
\__________/ (4s then 5s)
Now you may end up with a totally different layout, this sort of thing is left up to the implementation after all. I'm just showing you a couple of ways to figure it out.