4

执行检查并设置/清除标志是很常见的,例如:

if (some_test) {
   flag |= SOME_FLAG;
}
else {
   flag &= ~SOME_FLAG;
}

到目前为止我发现的一个方便的方法是......

flag = (some_test) ? (flag | SOME_FLAG) : (flag & ~SOME_FLAG);

这可以做成一个宏并且没问题,但是是否有一些小技巧可以避免两次引用标志?

flag(以防导致开销的多个实例化) 。

我正在寻找的示例(如果 C 可以对运算符进行三元运算)是......

flag ((some_test) ? (|=) : (&= ~) SOME_FLAG;

上面的例子只是为了描述我正在寻找的东西,当然它不会以目前的形式工作。

4

3 回答 3

8
flag |= SOME_FLAG

是一个表达式,所以你可以使用宏

#define SET_FLAG(flag, some_test) \
    ((some_test) ? ((flag) |= SOME_FLAG) : ((flag) &= ~SOME_FLAG))

它只计算flag一次,当你使用它时,你只需要输入flag一次。

SET_FLAG(a->b->c->d, test);
于 2012-11-07T03:26:58.877 回答
3

我知道您不想两次访问标志。但你应该确定这就是成本所在。通常,条件跳转更昂贵。在我使用的最后一个嵌入式处理器上,最快的代码应该是这样的:

 flag &= ~(SOME_FLAG);
 flag |= (some_test!=0) * SOME_FLAG;
于 2012-11-07T03:31:35.833 回答
0

如果你想定义一个宏并让它避免两次评估掩码,那么你可以这样做:

#define SETT(FLAG, MASK_T, MASK, TEST) \
do {\
  MASK_T mask = (MASK);\
  FLAG &= ~mask;\
  FLAG |= ((TEST) != 0) * mask;\
}\
while(false)

#define SET(FLAG, MASK, TEST) SETT(FLAG, unsigned, MASK, TEST)
于 2012-11-07T03:39:09.843 回答