Question

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 TOTAL_ELEMENTS 1021

typedef struct UINT1024_tag
{
   UINT8 byte[128];
} UINT1024;

typedef struct flags_tag
{
   UINT1024:TOTAL_ELEMENTS;
} flags_t;

When I try compiling this, I get the error message, "error: bit-field `<anonymous>' has invalid type"

Can bit-fields only be used on certain types? I thought that if I defined a large-enough variable, the massive bitfield needed for my application could then be defined because the bitfield has to be no larger than the type used to define it.

Any thoughts or suggestions would be appreciated.

Was it helpful?

Solution

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.

OTHER TIPS

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).

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));
}

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...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top