I have the following problem, I am assigning a number of bits within structures that are in a union.I trying to recombine them with a separate structure in that same union. However, when I assign mvUpper in Individual I lose that data or a significant bit based on the value I am assigning in Individual.(Please note I only lose data upon the portions I recombine in notIndividual) Please disregard the name, this was my investigation of unions before implementation.
#include <stdio.h>
#include <string.h>
typedef union testing
{
struct Individual
{
unsigned short mt : 10;
unsigned short mlbl : 3;
unsigned short mvUpper :3;
unsigned short mvLower :3;
unsigned short mlUpper :2;
unsigned short mlLower :5;
}Individual;
struct bE
{
unsigned int woo: 26;
}bE;
struct notIndividual
{
unsigned short mt : 10;
unsigned short mlbl : 3;
unsigned short mv :6 ;
unsigned short ml : 7;
}notIndividual;
} testing;
int main(int argc, char* argv[]){
testing dothis;
memset(&dothis,0,(sizeof(dothis)));
printf("THIS IS THE SIZE of union%lu\n",sizeof(dothis));
//printf("SIZE %d",sizeof(dothis.Individual));
//printf("NOT SIZE %d",sizeof(dothis.notIndividual));
dothis.Individual.mvUpper=3;
printf("Testing MT%u\n",dothis.Individual.mt);
printf("Testing MLBL %u\n",dothis.Individual.mlbl);
printf("Testing MVUpper %u\n",dothis.Individual.mvUpper);
printf("Testing MVLower %u\n",dothis.Individual.mvLower);
printf("Testing ML Upper %u\n",dothis.Individual.mlUpper);
printf("Testing ML Lower %u\n",dothis.Individual.mlLower);
printf("Testing Mt %u\n",dothis.notIndividual.mt);
printf("Testing Mlbl %u\n",dothis.notIndividual.mlbl);
printf("Testing MV %u \n",dothis.notIndividual.mv);
printf("Testing ML %u\n",dothis.notIndividual.ml);
printf("THIS IS THE WORD %u\n", dothis.bE.woo>>21);
return 1;
}
This is the output I can't understand
THIS IS THE SIZE of union4
Testing MT0
Testing MLBL 0
Testing MVUpper 3
Testing MVLower 0
Testing ML Upper 0
Testing ML Lower 0
Testing Mt 0
Testing Mlbl 0
Testing MV 0
Testing ML 0
THIS IS THE WORD 0
I was trying to test out an easy way of bit-shifting through unions.
CodePudding user response:
To preface, the organization of bitfields within a struct is implementation defined, so you can't reliably depend on a certain layout. That being said, here's what it most likely happening.
The base type for each of your bitfields is unsigned short
. So the compiler will try to group each of the bitfields into units of that size.
For the first struct, the layout is as follows:
struct Individual
{
unsigned short mt : 10; // 10 bits used in unit 0
unsigned short mlbl : 3; // 13 bits used in unit 0
unsigned short mvUpper :3; // 16 bits used in unit 0
unsigned short mvLower :3; // 3 bits used in unit 1
unsigned short mlUpper :2; // 5 bits used in unit 1
unsigned short mlLower :5; // 10 bits used in unit 1
}Individual;
And the second:
struct notIndividual
{
unsigned short mt : 10; // 10 bits used in unit 0
unsigned short mlbl : 3; // 13 bits used in unit 0
unsigned short mv :6 ; // 6 bits used in unit 1 (not enough in unit 0)
unsigned short ml : 7; // 13 bits used in unit 1
}notIndividual;
If you change all of your bitfields to have base type unsigned int
, the bitfields will be more packed and you'll get the result you expect.