!0 のビットパターンと C における bool
C99 からは C 言語で bool が使用できるが、互換性のため、以下のようなコードが書かれることが多い。
#ifdef HAVE_STDBOOL_H #include <stdbool.h> #else typedef enum { false=0, true=!false } bool; #endif
ここで気になるのは、
true=!false
の部分で、これはいったいどういうビットパターンになるのだろうか。
enum はたいてい int と同じ*1なので、32bit 環境なら 32bit すべてに 1 が立っているのかと思ったが、どうやらそうではないようだ。
この例では、x に "NOT y" の結果を格納する。これは、Cおよび C++の論理「否定」演算子 "!" (エクスクラメーションマーク)とは異なる。こちらは与えられた数値全体をひとつのブーリアンとして扱う。
ビット演算 - Wikipedia
どうやら NOT とは異なり、!0 の場合は、0 に対する論理否定になるので、値としては 1 になる。
printf("%d %d %d\n", !0 !1 !2);
この場合の出力は
1 0 0
となる。
だったら
typedef enum { false=0, true=1 } bool;
でも
typedef enum { false, true } bool;
でも結果は同じだけど、あえて !false を使うのはどういうメリットがあるのだろうか。
また、bool のために 4 バイトも使うのは非常にもったいないと感じるんだけど、stdbool.h の実装はどうなっているんだろう。
*1:これも経験的に知っているだけで、実際の仕様がどうなっているのかはわからない。C は本当にわからないことだらけだ。