Error trying to define a 1,024-bit (128 Byte) Bit Field

前端 未结 4 1754
走了就别回头了
走了就别回头了 2021-01-06 10:32

I would like to define a large bitfield for the purpose of quickly monitoring the status a very large structure of elements. Here is what I have so far:

#define T         


        
相关标签:
4条回答
  • 2021-01-06 10:43

    As other have said, the C standard doesn't allow bit-fields to exceed the size of their attached integer type.

    I'd suggest using plain arrays with some macro magic:

    #include <limits.h>
    #include <stdio.h>
    #include <string.h>
    
    // SIZE should be a constant expression
    // this avoids VLAs and problems resulting from being evaluated twice
    #define BITFIELD(SIZE, NAME) \
        unsigned char NAME[(SIZE) / CHAR_BIT + ((SIZE) % CHAR_BIT != 0)]
    
    static inline void setbit(unsigned char field[], size_t idx)
    { field[idx / CHAR_BIT] |= 1u << (idx % CHAR_BIT); }
    
    static inline void unsetbit(unsigned char field[], size_t idx)
    { field[idx / CHAR_BIT] &= ~(1u << (idx % CHAR_BIT)); }
    
    static inline void togglebit(unsigned char field[], size_t idx)
    { field[idx / CHAR_BIT] ^= 1u << (idx % CHAR_BIT); }
    
    static inline _Bool isbitset(unsigned char field[], size_t idx)
    { return field[idx / CHAR_BIT] & (1u << (idx % CHAR_BIT)); }
    
    int main(void)
    {
        BITFIELD(1025, foo);
        printf("sizeof foo = %u\n", sizeof foo);
    
        memset(foo, 0, sizeof foo);
        printf("%i", isbitset(foo, 1011));
    
        setbit(foo, 1011);
        printf("%i", isbitset(foo, 1011));
    
        unsetbit(foo, 1011);
        printf("%i", isbitset(foo, 1011));
    }
    

    Hopefully, I didn't mess up the bit ops...

    0 讨论(0)
  • 2021-01-06 10:55

    use

     UINT128 blaha;
    

    You're not defining a bitfield.

    I'm not sure you understand what a bitfield is. I bitfield is a number of bits. Not an array of structs or similar. What exactly are you expecting that your code should do?

    Edit: oh I see now. No, you can't use your own types, just ints.

    Try this (untested code):

    struct bit1024 {
      unsigned char byte[128];
    };
    struct bit1024 foo;
    void
    set(struct bit1024*lala, int n, int v)
    {
      lala->byte[n/8] |= 1<<(n % 8);
      if (!v) {
        lala->byte[n/8] ^= 1<<(n % 8);
      }
    }
    int
    get(struct bit1024*lala, int n)
    {
      return 1 & (lala->byte[n/8] >> (n % 8));
    }
    
    0 讨论(0)
  • 2021-01-06 10:56

    Bit fields must fit within a single int, you can't use arbitrary sizes. Honestly the ANSI bitfield implementation is kinda broken. It misses a lot of other stuff too, like control over padding and layout that real-world applications usually need. I'd consider writing some macros or accessor functions to abstract the larger sizes and giving up on the bitfield syntax.

    0 讨论(0)
  • 2021-01-06 10:56

    In standard C language bit-fields can only be defined with a restricted set of types. In C89/90 these types are limited to int, signed int and unsigned int (a little-known detail is that in this context int is not guaranteed to be equivalent to signed int). In C99 type _Bool was added to the supported set. Any other types cannot be used in bit-field declaration.

    In practice, as a popular extension, compilers normally allow any integral type (or also enum type) in bit-field declaration. But a struct type... No, I'm not aware of any compiler that would allow that (let alone that it doesn't seem to make much sense).

    0 讨论(0)
提交回复
热议问题