Макросы для установки и очистки битов - PullRequest
4 голосов
/ 05 июня 2010

Я пытаюсь написать несколько простых макросов, чтобы упростить задачу установки и очистки битов, что должно быть простой задачей, однако я не могу заставить их работать правильно.

#define SET_BIT(p,n) ((p) |= (1 << (n)))
#define CLR_BIT(p,n) ((p) &= (~(1) << (n)))

Ответы [ 3 ]

10 голосов
/ 05 июня 2010

Попробуйте

#define CLR_BIT(p,n) ((p) &= ~((1) << (n)))

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

static inline void set_bit(long *x, int bitNum) {
    *x |= (1L << bitNum);
}
8 голосов
/ 05 июня 2010

Одна очевидная проблема заключается в том, что ((p) &= (~(1) << (n))) должно быть ((p) &= ~(1 << (n))).

Кроме того, вы должны быть осторожны с шириной целочисленных типов. Если вы используете unsigned long, вам может понадобиться (например,) ((p) |= (1UL << (n)))

0 голосов
/ 05 июня 2010

Тьфу. У вас нет локального набора функций, чтобы сделать это для вас? Это скрыло бы любую магию, которая должна происходить при пропуске границ слова.

В противном случае, как вышеперечисленное терпит неудачу? Они выглядят «хорошо», но я все равно предпочел бы делать такие вещи вручную, если функции недоступны. Макросы просто скрывают неприятные ошибки при выполнении подобных действий. Передача подписанного против неподписанного и т. Д. Не будет пойман с макросами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...