Определение битовых флагов с помощью #define в C ++ - PullRequest
2 голосов
/ 07 марта 2011

Я изучаю битовые флаги. Я уже знаю, как они работают и как они определены в struct. Однако я не уверен, могут ли они быть определены в директиве препроцессора #define, например:

#define FLAG_FAILED:1

Эта директива определения препроцессора является struct определением битового флага?

PS: я уже сталкивался с этим связанным вопросом, но он не ответил на мой вопрос: # определенные битовые флаги и перечисления - мирное сосуществование в "c" Кроме того, если вы можете указать мне некоторую информацию относительно директив препроцессора, я был бы признателен за это.

Ответы [ 3 ]

4 голосов
/ 07 марта 2011

Любой #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 голос
/ 07 марта 2011

#define FLAG_FAILED:1 на самом деле не битовый флаг в том смысле, что большинство людей знают как «битовый флаг».Это также плохой синтаксис.

Флаги битов обычно определяются так, что у вас есть тип , и вы включаете «биты», «устанавливая» их.Вы выключаете их, «убирая» флаг.Для сравнения, если битовый флаг включен, вы используете то, что называется побитовый оператор AND (например, & ).

Таким образом, ваш BIT0 (например, 2 ^0) будет определено как BIT0 = 0x00000001 и BIT1 (например, 2 ^ 1) как BIT1 = 0x00000002.Если вы хотите придерживаться определить , вы можете сделать это с настройкой и очисткой:

#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.

0 голосов
/ 07 марта 2011

Форма для определения побитовых значений с помощью #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 )
...