Defining Bit-Flags Using #define in C++
I'm learning about bit-flags. I already know how they work and how they are defined in a struct
. However, I'm unsure if they can be defined in a #define
preprocessor directive like this:
#define FLAG_FAILED:1
Is this preprocessor define directive the as a struct
bit-flag definition?
PS: I've already come across this related question but it didn't answer my question: #defined bitflags and enums - peaceful coexistence in "c". Also, if you can point me towards some开发者_StackOverflow中文版 information regarding preprocessor directives, I would appreciate that.
Any #define that you want to use to inject bitflags into a struct must take the form:
#define IDENTIFIER SUBSTITUTED_CODE
In your postulated use...
#define FLAG_FAILED:1
The identifier contains the colon, which makes it invalid.
You could do something like this:
#define FLAG_FAILED int flag_failed :1
struct X
{
char a;
FLAG_FAILED;
int b;
...
};
It's not clear why you're considering using a define for the bit field anyway. If you just want to be able to vary the field length, then:
#define FLAG_FAILED_BITS 1
struct X
{
unsigned flag_failed :FLAG_FAILED_BITS;
};
...or...
#define FLAG_FAILED_BITS :1
struct X
{
unsigned flag_failed FLAG_FAILED_BITS;
};
#define FLAG_FAILED:1
is not really a bit flag in the sense that what most people know as a "bit flag". It's also bad syntax.
Bit flags typically are defined so that you have a type and you turn "on" bits by "setting" them. You turn them "off" by "clearing" the flag. To compare if the bit flag is on, you use what is called the bitwise operator AND
(e.g. &).
So your BIT0 (e.g. 2^0) would be defined as BIT0 = 0x00000001
and BIT1 (e.g. 2^1) as BIT1 = 0x00000002
. If you wanted to stick with define you could do it this way with setting and clearing:
#ifndef setBit
#define setBit(word, mask) word |= mask
#endif
#ifndef clrBit
#define clrBit(word, mask) word &= ~mask
#endif
or as a template
template<typename T>
inline T& setBit(T& word, T mask) { return word |= mask; }
template<typename T>
inline T& clrBit(T& word, T mask) { return word &= ~mask; }
If you want to set the bit, so to speak, you could have a state set as follows:
setBit(SystemState, SYSTEM_ONLINE);
or
setBit(SystemState, <insert type here>SYSTEM_ONLINE);
clearing would be the same just replace setBit
with clrBit
.
To compare, just do this:
if (SystemState & SYSTEM_ONLINE) { ... // do some processing
}
if this is in a struct
then, reference the struct
.
A form to define bitwise values with #define macros is:
#define BIT_ONE static_cast<int>( 1 << 0 )
#define BIT_TWO static_cast<int>( 1 << 1 )
#define BIT_THREE static_cast<int>( 1 << 2 )
精彩评论