Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating bitflag variables with large amounts of flags or how to create large bit-width numbers

Tags:

c

bitflags

Lets say I have an enum with bitflag options larger than the amount of bits in a standard data type:

enum flag_t {
FLAG_1 = 0x1,
FLAG_2 = 0x2,
...
FLAG_130 = 0x400000000000000000000000000000000,
};

This is impossible for several reasons. Enums are max size of 128 bits (in C/gcc on my system from experimentation), single variables are also of max size 128 bits etc.

In C you can't perform bitwise operations on arrays, though in C++ I suppose you could overload bitwise operators to do the job with a loop.

Is there any way in C other than manually remembering which flags go where to have this work for large numbers?

like image 342
J V Avatar asked Feb 16 '23 14:02

J V


2 Answers

This is exactly what bit-fields are for.

In C, it's possible to define the following data layout :

struct flag_t 
{
     unsigned int flag1 : 1;
     unsigned int flag2 : 1;
     unsigned int flag3 : 1;
(...)
     unsigned int flag130 : 1;
(...)
     unsigned int flag1204 : 1;   // for fun
};

In this example, all flags occupy just one bit. An obvious advantage is the unlimited number of flags. Another great advantage is that you are no longer limited to single-bit flags, you could have some multi-value flags merged in the middle.

But most importantly, testing and attribution would be a bit different, and probably simplified, as far as unit operations are concerned : you no longer need to do any masking, just access the flag directly by naming it. And by the way, use the opportunity to give these flags more comprehensive names :)

like image 198
Cyan Avatar answered May 13 '23 06:05

Cyan


Instead of trying to assign absurdly large numbers to an enum so you can have a hundreds-of-bits-wide bitfield, let the compiler assign a normal zero-based sequence of numbers to your flag names, and simulate a wide bitfield using an array of unsigned char. You can have a 1024-bit bitfield using unsigned char bits[128], and write get_flag() and set_flag() accessor functions to mask the minor amount of extra work involved.

However, a far better piece of advice would be to look at your design again, and ask yourself "Why do I need over a hundred different flags?". It seems to me that what you really need is a redesign.

like image 34
This isn't my real name Avatar answered May 13 '23 07:05

This isn't my real name