4

チェックを実行してフラグを設定/クリアするのが一般的です。たとえば、次のようになります。

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

これまでに見つけた便利な方法は...

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

これをマクロにすれば問題ありませんが、フラグを 2 回参照するのを避けるためのビット操作の魔法はありますか?

(複数のインスタンス化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 に 2 回アクセスしたくないことはわかっています。しかし、それがコストであることを確認する必要があります。多くの場合、条件付きジャンプはよりコストがかかります。私が最後に取り組んだ組み込みプロセッサでは、最速のコードは次のようになります。

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

マクロを定義して、マスクを 2 回評価しないようにする場合は、次のようにします。

#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 に答える