I came across some code (it's in a library from Microchip) which has a union.
All was good, until I saw it assigned values to different members of the union right after each other. My immediate thought was "They are over writing the same location..." Then I decided to do a test. By every measure I thought I understood, this union should be one byte (8 bits). But it's not... it's 4 bytes.
#pragma pack(1)
typedef union _STATUS
{
BYTE Val;
struct {
unsigned BC8 : 1;
unsigned BC9 : 1;
unsigned BSTALL : 1;
unsigned DTSEN : 1;
unsigned INCDIS : 1;
unsigned KEN : 1;
unsigned DTS : 1;
unsigned UOWN : 1;
};
struct {
unsigned BC8 : 1;
unsigned BC9 : 1;
unsigned PID0 : 1;
unsigned PID1 : 1;
unsigned PID2 : 1;
unsigned PID3 : 1;
unsigned : 1;
unsigned UOWN : 1;
};
struct {
unsigned : 2;
unsigned PID : 4;
unsigned : 2;
};
} STATUS;
void PrintIt() {
printf("Size of UNION is %d \n", sizeof(STATUS));
}
It should be the largest of any member, which each member is only 8 bits.
The code that caught my eye and made me investigate this is:
STAT.BC9 = 0;
STAT.BC8 = 0;
STAT.Val |= byteToSend;
Which the third line merges into the values from the first and second.
So I wanted to test it, it's coming out as 4 bytes, not one. I even tested it in a few different compilers (hence the #pragma usage for MS Visual C).
Each member is exactly 8 bits, and the last two struct overlap to place the PID values in the same memory location. And yet this is 4 bytes every way I use a compiler to evaluate it.
Is there something in the behavior of adding structs to unions?
Any explanation is appreciated.