久々のバグです。char a
と BYTE b
が等しいことを期待した評価式が期待通りに動かないというもので暗黙の型変換によって実は期待通りの比較がされていなかったというオチでした。
#include <stdio.h> #include <windows.h> #define CONDITION(x) printf (#x " : %s ", (x) ? "true" : "false" ) void main () { char a = (char) 0xff; BYTE b = 0xff; /*eq.1*/ CONDITION (a == b); /*eq.2*/ CONDITION ((signed int) a == (signed int) b); /*eq.3*/ CONDITION ((BYTE) a == b); /*eq.4*/ CONDITION (a == (char) b); }
最初の実装がeq.1です。a, b 共に内部表現は(1111 1111)ですから暗黙の型変換がされても
評価式は真になる(←ここがダウト)とものと思い込んでいました。暗黙の型変換では『両方の値を不足無く表現できる符号付きの型に合わせる』らしいです。この場合、左辺が(char) 0xff → -1、右辺が(BYTE) 0xff → 255ですから char の一つ上、両者を表現できる signed int に合わせて比較されることになります。つまり実際のところ、eq.1は暗黙の型変換によってeq.2として評価されていたのでした。
タネを明かせば何のことはないのですが10分ばかし頭を抱えてしまいました。長年やってきて恥ずかしいバグです。
対策を挙げるとすればeq.3またはeq.4となります。今回、a が UDP パケットのバイトデータだったので変数の意味を考えれば a は BYTE 型で宣言し直すのが筋かもしれません。