在C ++中使用#define定义位标志

时间:2011-03-07 01:15:20

标签: c++ struct c-preprocessor bit flags

我正在学习比特旗。我已经知道它们是如何工作的以及如何在struct中定义它们。但是,我不确定它们是否可以在#define预处理器指令中定义,如下所示:

#define FLAG_FAILED:1

这个预处理器定义指令是struct位标志定义吗?

PS:我已经遇到过这个相关问题,但它没有回答我的问题:#defined bitflags and enums - peaceful coexistence in "c"。另外,如果你能指出我有关预处理器指令的一些信息,我将不胜感激。

3 个答案:

答案 0 :(得分:4)

要用于将bitflags注入结构的任何#define必须采用以下形式:

#define IDENTIFIER SUBSTITUTED_CODE

在假设的使用中......

#define FLAG_FAILED:1

标识符包含冒号,使其无效。

你可以这样做:

#define FLAG_FAILED int flag_failed :1

struct X
{
    char a;
    FLAG_FAILED;
    int b;
    ...
};

目前尚不清楚为什么要考虑使用比特字段的定义。如果您只想改变字段长度,那么:

#define FLAG_FAILED_BITS 1

struct X
{
    unsigned flag_failed :FLAG_FAILED_BITS;
};

...或...

#define FLAG_FAILED_BITS :1

struct X
{
    unsigned flag_failed FLAG_FAILED_BITS;
};

答案 1 :(得分:1)

#define FLAG_FAILED:1在大多数人都知道的“位旗”的意义上并不是真正的旗帜。这也是错误的语法。

通常会定义位标志,以便您具有类型并通过“设置”它们来打开“开”位。你通过“清除”旗帜将它们“关闭”。要比较位标志是否打开,您可以使用所谓的按位运算符AND(例如& )。

因此,您的BIT0(例如2 ^ 0)将定义为BIT0 = 0x00000001,BIT1(例如2 ^ 1)为BIT1 = 0x00000002。如果您想坚持 define ,您可以通过设置和清除这样做:

#ifndef setBit
#define setBit(word, mask) word |= mask
#endif

#ifndef clrBit
#define clrBit(word, mask) word &= ~mask
#endif

或作为模板

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

如果要设置该位,可以这么说,您可以设置如下状态:

setBit(SystemState, SYSTEM_ONLINE);

setBit(SystemState, <insert type here>SYSTEM_ONLINE);

清算只需将setBit替换为clrBit

要比较,只需这样做:

if (SystemState & SYSTEM_ONLINE) { ... // do some processing 

}

如果这是struct,则引用struct

答案 2 :(得分:0)

使用#define宏定义按位值的表单是:

#define BIT_ONE    static_cast<int>( 1 << 0 )
#define BIT_TWO    static_cast<int>( 1 << 1 )
#define BIT_THREE  static_cast<int>( 1 << 2 )