_Bool
読み:アンダースコア-ブール
外語:_Bool

 ISO/IEC 9899:1999(いわゆるC99、日本語規格はJIS X 3010:2003)から追加された予約語の一つ。論理型を宣言する。
目次

概要
 元々Cには論理型がなかった。Cの後継とも言えるC++では、Cにはない予約語boolが追加されている。
 そしてCでも、C99から論理型として_Boolが予約語に追加された。
 本来はC++と同様にboolとしたかったが、既に多くのCプログラムで独自にbool型を定義してしまっていたため、混乱を避けるためにいくつかの小細工をしている。

特徴

大きさと論理値
 _Bool型は、0または1を格納するのに充分な大きさを持っている、符号無しの整数型である。
 つまり、この変数には0や1を「即値で」代入することになる。
 とは言え、これでは不便かつ分かりにくいので、C99では「stdbool.h」という新しいヘッダーファイルが定義された。この中で、次のような定義がされている。
 #define true 1
 #define false 0
 つまり、C++のそれとは異なり、このtrue/falseは予約語ではなく単なるマクロで、int型の定数である。

別名定義
 _Boolという「変な」予約語を直接使うことは考えにくい。入力しにくく覚えにくく、その上C++とも違い使いにくいからである。
 そこでC99標準は、やはりstdbool.hヘッダーファイルで、次のような別名定義を用意した。
 #ifndef __cplusplus
 #define bool _Bool
 #endif
 stdbool.hをincludeするだけでboolが定義される。C99標準は、マクロboolを_Boolに展開する。
 これにより、表向きはC++と何ら変わらない使い勝手が実現できる。

型変換
 _Bool型変数はC++のboolよりも更に一般の整数型変数に近い性質を持っている。この型には0と1しか格納できないが、それ以外は他の整数型変数となんら変わらずに利用できる。
 他の変数型や直定数(リテラル)を_Bool型にキャストした場合、元の値が0なら0、さもなくば1が_Bool型変数に代入される。
 逆に_Bool型を他の型にキャストした場合、結果は内容に応じ、0または1となる。

補足

カーネル空間
 カーネル空間はC標準とは異なる環境だが、boolが使えるよう配慮されている。

Linux
 Linuxのカーネル空間の場合、次のように定義されている。
 kernel/include/linux/types.h

typedef _Bool bool;

 kernel/include/linux/stddef.h

enum { false = 0, true = 1 };

 この二つのヘッダーファイルはlinux/kernel.hからincludeされている。
 このためカーネル空間では、linux/kernel.hをincludeしておけば、bool/true/falseがC++と同様に利用できる。

FreeBSD
 FreeBSDのカーネル空間の場合、次のように定義されている。
 /usr/src/sys/sys/types.h

#if !defined(__bool_true_false_are_defined) && !defined(__cplusplus) #define __bool_true_false_are_defined 1 #define false 0 #define true 1 #if __STDC_VERSION__ < 199901L && __GNUC__ < 3 && !defined(__INTEL_COMPILER) typedef int _Bool; #endif typedef _Bool bool; #endif /* !__bool_true_false_are_defined && !__cplusplus */

 true/falseは#defineで、Cコンパイラーが古く_Boolがない場合はintでtypedefしたあと、boolを_Boolで定義していることが分かる。
 このためカーネル空間では、sys/types.hをincludeしておけば、bool/true/falseがC++と同様に利用できる。

stdbool.h

Linux
 Linuxのgccの場合、環境によって変わるが、例えば次のような場所にstdbool.hと定義がある。
 /usr/lib/gcc/x86_64-linux-gnu/4.4/include/stdbool.h

#define bool _Bool #define true 1 #define false 0

 Linuxの場合、比較的新しいgccに依存しており、Cの新しい仕様なども普通に用いているため、_Boolが使用できないような古いgccでは、そもそもビルドが通らない。
 最初から利用を想定していないためか、intで置き換えるような処理もない。

FreeBSD
 FreeBSDのstdbool.hは保守的で、古いCコンパイラーでincludeされることを想定し、次のように定義されている。

#ifndef __cplusplus #define false 0 #define true 1 #define bool _Bool #if __STDC_VERSION__ < 199901L && __GNUC__ < 3 && !defined(__INTEL_COMPILER) typedef int _Bool; #endif #endif /* !__cplusplus */

 つまり、_Boolが定義されていない古いCコンパイラーでは、boolは間接的にintのtypedefとして定義される。
 これはC99標準の要求ではないが、_Boolが無い環境であっても、boolは正常にコンパイルできる。

再検索