Home > other >  Why am I losing these bits while defining structs in unions
Why am I losing these bits while defining structs in unions

Time:12-21

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.

  • Related