ブール値との比較

Cには真偽を表す型はなく、アセンブラっぽく0が偽、それ以外が真となる。ついでにほとんどの一次式は値を持つ(戻り値の型がvoid以外は値を持つ)のでバグの温床になりやすい。


以上は枕でここからが本題。業務上のコーディングで以下のようなコードになった。

/* isHogeが真だったらhogeする */
if (isHoge == TRUE) {
    hoge();
}

上記でTRUEは1に定義してある。だがしかし、Cの仕様上、真は1とは限らない。上記の書き方は危険な書き方である。しかし、職場のコーディング規約は比較を省略することを許さない。暗黙の比較を排除する、という考えのようだ。
真は1とはかぎらないので、こういう場合は0と比較するのが常套手段だ。というわけで以下のように書き換えた。

/* isHogeが偽でなければhogeする */
if (isHoge != FALSE) {
    hoge();
}

これ読みやすいか?だいたい否定の文脈は読みにくいのだ。こんな書き方をするくらいなら、変数名がブール値であることを主張しているので以下の方がよっぽど読みやすい

/* isHogeが真だったらhogeする */
if (isHoge) {
    hoge();
}

で、結局どうしたかというと、じつはisHogeは関数の戻り値になっていて、真の時は1、偽の場合は0であることがAPI仕様上決まっているのであった。よっていかに落ち着いた

isHoge = getStatue();
/* isHogeが真だったらhogeする */
if (isHoge == TRUE) {
    hoge();
}

なんのことはない、最初に戻ったのであった。

で、結局どうなって欲しいのかというと、以下かな。

  1. 意味上ブール値の変数とTRUE/FALSEの比較はすべきではない。
  2. 否定形となるような比較はわかりにくいので避ける。
  3. NULLや'\0'との比較は略さない方がわかりやすい場合が多い。