_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は正常にコンパイルできる。
再検索