!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 は本当にわからないことだらけだ。