I have the following struct:
struct SysData
{
// Topic (32 bits)
UTL_UINT16_Tdef SystemID:11; // set to decimal 25
UTL_UINT16_Tdef TypeID:5; // set to 2 (telemetry type)
UTL_UINT16_Tdef ContentID; // set to decimal 1234
}
SysData MsgHdr;
MsgHdr.SystemID = 25;
MsgHdr.TypeID = 2;
MsgHdr.ContentID = 0;
If I do something like this:
unsigned int a;
memcpy(&a, &MsgHdr, sizeof(MsgHdr));
headerInfo[0] = a & 0x7FF;
headerInfo[1] = (a >> 16) & 31;
headerInfo[2] = (a >> 21) & 0xFFFF;
headerInfo[0] should have the value 25, but it has 36. What am I doing wrong?
You shouldn’t guess on the internal representation of SysData.Compiler may choose to pack bit fields together or not, to align them left or right, etc. It can even choose to map them to 32 bits integer for performances issue. You just can’t know. The unused part of the bitfield may contain garbage and it’s probably where you got your 36.
It’s strange, but not really hard to check. Change your 25 to other values and see what you get.
However, memcopying your structure to some unsigned int is probably not a good idea. Why don’t you access bitfield directly ? Like in
headerInfo[0] = MsgHdr.SystemID;that’s what bitfields are for. In your example the memcopy is just a loss of time (and also dangerous as you can see).