开发者

Defining Bit-Flags Using #define in C++

开发者 https://www.devze.com 2023-02-14 23:58 出处:网络
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:

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号