ビット演算子 & の優先順位が比較演算子 == より低いことによる誤動作
a & b == cと書くと、==の方が優先順位が高いため、a & (b == c)として解釈されます。意図した(a & b) == cとは異なる結果になります。
なぜエラーが出ないのか
出力: no
(エラーなし)- Cは何も報告しません。コンパイルも実行も正常に完了するためです
出力: no- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 #include <stdio.h> 2 3 int main(void) { 4 int flags = 6; 5 int mask = 2; 6 if (flags & mask == mask ) { ^ 7 printf("yes\n"); 8 } else { 9 printf("no\n"); 10 } 11 return 0; 12 }
==は&よりも優先順位が高いため、flags & mask == maskはflags & (mask == mask)として解釈されます。ビット演算と比較を混ぜるときは括弧で明示的にグループ化する必要があります。
直し方: flags & mask == mask を (flags & mask) == mask にします。
パターン2
1 #include <stdio.h> 2 3 int main(void) { 4 int bits = 12; 5 int test = 4; 6 if (bits & test == test ) { ^ 7 printf("yes\n"); 8 } else { 9 printf("no\n"); 10 } 11 return 0; 12 }
bits & test == testはbits & (test == test)、つまりbits & 1と解釈されます。12は偶数なので最下位ビットが0になり、常に0(偽)になってしまいます。
直し方: bits & test == test を (bits & test) == test にします。
パターン3
1 #include <stdio.h> 2 3 int main(void) { 4 int level = 8; 5 int flag = 8; 6 if (level & flag == flag ) { ^ 7 printf("yes\n"); 8 } else { 9 printf("no\n"); 10 } 11 return 0; 12 }
levelとflagが等しくても、優先順位のせいでlevel & (flag == flag)、つまりlevel & 1が計算されてしまい、期待した比較にはなりません。
直し方: level & flag == flag を (level & flag) == flag にします。
よくある誤解
算数の感覚では&も==も同じくらいの優先度に見えますが、Cの演算子優先順位表では比較演算子(==, !=, <, >など)はビット演算子(&, |, ^)よりも優先順位が高く設定されています。ビット演算と比較を混ぜるときは、必ず括弧で明示的にグループ化する必要があります。
まとめ
ビット演算子 & の優先順位が比較演算子 == より低いことによる誤動作は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。