まず、マクロを次のように修正する必要があります。
#define SETBIT(X,Y) ( (X) |= 1ULL << (Y) )
#define UNSETBIT(X,Y) ( (X) &= ~(1ULL << (Y)) ) )
そうすれば、次のようなコードSETBIT(a, 2) + 1;
が期待どおりに機能し、SETBIT(1+a, 2);
期待どおりにエラーが発生します。
()
おそらくそのようにマクロを使用することはありませんが、余分な括弧はとにかく無料であり、マクロ関連の問題を解決することは、常に余分なマクロやマクロを配置するような PITA になる可能性があり{}
ます。
追加: インライン アセンブリとビット ローテーション操作を使用する CPU を使用し、コンパイル時に不明であると仮定Y
すると、UNSETBIT を高速化して、NOT を回避できます... 疑似コード:
X = X OR (0xFFFFFFFFFFFFFFFE ROL Y)
次に、これらのマクロは可能な限り効率的ですが (C コンパイラはそれらを理想的なアセンブリ命令に最適化する必要があります)、次のようないくつかのビットを操作するマクロを提供する必要があります。
#define SET2BITS(X, B1, B2) ( (X) |= 1ULL << (B1) | 1ULL << (B2) )
また、式の中で使用するための関数のようなマクロは、状況によってはより効率的かもしれません (ただし、コンパイラの最適化はおそらく同じ最終結果を達成します):
#define BITSETVAL(X, B) ( (X) | 1ULL << (B) )