Search code examples
cbit-fields

Bit field structure arrays in C


How can I create a bit-field array with variable size? The following code is what I tried, which didn't work.

#include <stdio.h>
int main()
{
    int n=4;
    struct bite{
        unsigned a1:2;
        unsigned a2:2;
            :
            :
        unsigned a(n-1):2;
        unsigned a(n):2;
    }bits;

    for(i=1;i<=n;i++)
        bits.a[i]=i;

    for(i=1;i<=n;i++)
        printf("%d ",bits.a[i]);

    return 0;
}

Solution

  • The members of a struct cannot be defined at runtime.

    You could simulate a bit array using a char array and some macros.

    #define BitArray(array, bits) \
      unsigned char array[bits / 8 + 1]
    
    #define SetBit(array, n) \
      do { array[n / 8] |= (1 << (n % 8)) } while (0)
    #define GetBit(array, n) \
      ((array[n / 8] >> (n % 8)) & 1)
    
    int main(void)
    {
      BitArray(bits, 42); /* Define 42 bits and init to all 0s
                                   (in fact this allocates memory for (42/8 + 1) * 8 bits). */
    
      SetBit(bits, 2); /* Set bit 2. */
      int bit2 = GetBit(bits, 2); /* Get bit 2 */
    
      ...
    

    Similar for 2-bit words are per your code:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #define Define2BitWordArray(array, two_bit_words) \
      unsigned char array[two_bit_words / 4 + 1]
    
    #define Set2BitWord(array, n, value) \
      do { array[n / 4] |= (unsigned char)((value & 0x11) << (2 * (n % 4))); } while (0)
    #define Get2BitWord(array, n) \
      ((array[n / 4] >> (2 * (n % 4))) & 0x11)
    
    int main(void)
    {
      size_t n = 10;
      Define2BitWordArray(bits, n); /* Define 10 two-bits words
                                      (in fact this allocates memory 
                                      for (10/4 + 1) * 4 two-bit bits). */
      memset(bits, 0, sizeof bits); /* Set all bits to 0. */
    
      for(size_t i = 0; i < n; i++) /* C array's indexes are 0-based. */
      {
        Set2BitWord(bits, i, i);
      }
    
      for(size_t i = 0; i < n; i++)
      {
        printf("%d ", Get2BitWord(bits, i));
      }
    }