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