Grey
Grey

Reputation: 133

I can't manipulate bit fields in C

I wanted to implement LFSR(linear feedback shift registers) in C to generate random bits. When I try to modify an individual bit or just assign a short value to memory block, all the bits set to 1. How can I stop this from happening?

struct lfsr{
    //... 
    union{
        unsigned short ff_0 : 1;
        unsigned short ff_1 : 1;
        //... 
        unsigned short ff_f : 1;
        unsigned short ff;
    }flip_flops;
};

int main() {
    struct lfsr gen;
    gen.flip_flops.ff = 1;      //all the ff's set to 1
    gen.flip_flops.ff = htons(0x0001);//all the ff's set to 1
    gen.flip_flops.f_0 = 1;     //all the ff's set to 1
    gen.flip_flops.f_0 = 0;     //all the ff's set to 0
}

Upvotes: 3

Views: 137

Answers (3)

AmeyaVS
AmeyaVS

Reputation: 1034

You are probably understanding the union differently. All the bit-fields are aliased at the same location. You probably want to do something like this:

struct lfsr{
  //... 
  union{
    struct {
      unsigned short ff_0 : 1;
      unsigned short ff_1 : 1;
      //... 
      unsigned short ff_f : 1;
    };
    unsigned short ff;
  }flip_flops;
};

You can have a look here about differences between a struct and a union.

Update:
As per the comments @the-busybee regarding the alignment of bit-fields based on architecture is also worth noting regarding portability of the code across various architectures.
Refer answers here regarding the discussion on bit endianess.

Upvotes: 4

The problem is that the union means that each and every one of the one-bit bitfield members access the exact same one bit. What you want to do is

union lfsr{
    //... 
    struct {
        unsigned short ff_0 : 1;
        unsigned short ff_1 : 1;
        //... 
        unsigned short ff_f : 1;
    }flip_flops;

    unsigned short ff;
};

Upvotes: 8

Swanand
Swanand

Reputation: 4115

When you declare an Union, all elements of Unions are part of same memory. They are just accessed differently.

 union{
        unsigned short ff_0 : 1;
        unsigned short ff_1 : 1;
        //... 
        unsigned short ff_f : 1;
        unsigned short ff;
    }flip_flops;

Here, ff_0 and ff_1 are same memory and so is ff That is why, when you assign a value to ff_0, it automatically assigned to ff_1. So what you are observing is correct.

What you should do is, create a structure with 15 bit fields. Then union should be struct and unsigned short.

Upvotes: 3

Related Questions