boolはネイティブCタイプですか?


265

Linuxカーネルコードがboolを使用していることに気づきましたが、boolはC ++型であると思いました。boolは標準のC拡張(ISO C90など)またはGCC拡張ですか?


2
これについては、comp.lang.c FAQのセクション9で説明しています。
キーストンプソン


Linuxカーネルは、C90の拡張として-std=gnu89サポートする_Boolを使用します。「include / linux / types.h」にはがありtypedef _Bool bool;ます。
Ian Abbott

また、FWIW、Linuxカーネル2.6.19は最初に使用したバージョンtypedef _Bool bool;(commit 6e21828743247270d09a86756a0c11702500dbfb)であり、GNU C 3.2以降が必要でした。
Ian Abbott

回答:


368

bool 現在のC-C99には存在しますが、C89 / 90には存在しません。

C99では、ネイティブタイプは実際にはと呼ばれて_Boolいますboolが、で定義されている標準ライブラリマクロですstdbool.h(これはに解決されると予想されています_Bool)。タイプのオブジェクトは_Bool0または1を保持しますが、trueおよびfalseはからのマクロでもありますstdbool.h

ところで、これは、Cプリプロセッサが含ま#if trueれてい#if 0ない限り、Cプリプロセッサが解釈することを意味することに注意してくださいstdbool.h。一方、C ++プリプロセッサはtrue、言語リテラルとしてネイティブに認識する必要があります。


62
2011年に発行された新しいISO C標準があります(この回答が投稿された後)。ANSIは、いつものように、ANSI規格としてISO C11規格を採用しています。歴史的な理由から、「ANSI C」という語句は一般に(ただし、正しくはありません)、ANSI C89 / ISO C90標準で定義された言語を指します。現在、C標準は最初にISOによって公開されており、3つのISO C標準が採用されているため、採用レベルはさまざまであるため、標準が公開された年(ISO C90、ISO C99、ISO C11)を参照することをお勧めします。錯乱。
キーストンプソン

8
これ_Boolは、1ビットのメモリを消費することを意味しますか?
ジェレミア

27
@Geremia:いいえ。なぜですか?Cでは、アドレス可能な各オブジェクトは少なくとも1バイトを占有する必要があります。また、実際の実装で_Boolは、通常、1バイトのメモリが必要です。ただし、言語仕様では_Bool、ビットフィールドタイプとしての使用を明示的に許可しています。つまり、ビットフィールドを使用すると、_Bool値を1つのビット(より大きな構造体の内部)に圧縮できます。
AnT

@AnT _Bool値を直接アドレス指定できる(つまり1バイトのサイズにする)ことができ、ビットフィールドにも参加できるのはなぜですか。の配列で_Boolも、すべての要素がアドレス指定可能である必要があります(例:)_Bool* ptr = &boolArray[123]

118

C99は、組み込みの追加_Boolデータ型(参照ウィキペディアの詳細を)、そしてあなたならば#include <stdbool.h>、それが提供boolするマクロとして_Bool

特にLinuxカーネルについて質問しました。include / linux / types.hに typedef が存在することを前提_Boolとし、boolそれ自体を提供します。


26
理由については、その定義がレガシーコードとの衝突を引き起こす可能性がある場合に、未定義にして再定義できるようにすることです。
クリフォード

32

いいえ、boolISO C90 にはありません。

標準C(C99ではない)のキーワードのリストは次のとおりです。

  • auto
  • break
  • case
  • char
  • const
  • continue
  • default
  • do
  • double
  • else
  • enum
  • extern
  • float
  • for
  • goto
  • if
  • int
  • long
  • register
  • return
  • short
  • signed
  • static
  • struct
  • switch
  • typedef
  • union
  • unsigned
  • void
  • volatile
  • while

カーネルと標準で使用されているCとのその他の相違点について説明している記事は次のとおりです。http//www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html


6
実用的な目的のために、それでもまともなコンパイラのサポートがない限り、それは本当に重要ですか?gccにも最近までC99機能の半分はありませんでした
。MSVCに

5
@Jonathan Leffler、質問者は特にISO C90について尋ねました。:)実際、通常、人々がANSI Cに言及するとき、彼らはC90を意味します。C99を使用していないか、実際に使用する予定であり、多くの人が同じように感じていると思います。
BobbyShaftoe

6
@BobbyShaftoe:元の投稿者は、コメントでC90が一例であると明確に述べていました。
キーストンプソン

32

C99ではstdbool.hにありますが、C90ではtypedefまたはenumとして定義する必要があります。

typedef int bool;
#define TRUE  1
#define FALSE 0

bool f = FALSE;
if (f) { ... }

または:

typedef enum { FALSE, TRUE } boolean;

boolean b = FALSE;
if (b) { ... }

5
typedefの動作はC99の動作boolとは異なり、多くのコンパイラーのbit型の動作とも異なることに注意してください。たとえば、bool x=4294967296LL;またはC99では1にbool x=0.1;設定さxれますが、ほとんどのtypedefバージョンはゼロに設定される可能性があります。
スーパーキャット2016年

17
/* Many years ago, when the earth was still cooling, we used this: */

typedef enum
{
    false = ( 1 == 0 ),
    true = ( ! false )
} bool;

/* It has always worked for me. */

16
初期値は完全に不要です。typedef enum { false, true };同様に良いです。より明示的に主張する場合は、と書くことができますtypedef enum { false = 0, true = 1 };。(または#include <stdbool.h>、コンパイラがサポートしている場合、それは14年間標準でした。)
キース・トンプソン

9
@KeithThompson初期値は不要な場合がありますが、この答えは非常に洗練された方法でそれらを選択します。任意の値ではなく、言語独自のセマンティクスを使用してコンパイラに決定させます。
MestreLion、2015

11
@MestreLion:言語自体のセマンティクスtypedef enum { false, true } bool;は、期待どおりに機能することを保証します。1 == 0かつ! falseエレガントではありません、彼らは単に難読化されています。コンパイラが決定することはありません。言語で定義されているセマンティクスに従う必要があります。
キース・トンプソン、

11
@KeithThompson:私はそれらが難読化されているとは思わない、著者の意図は最も「自然な」値を選択することだったと思う:false言語が不平等を評価すべきであると言う値とtrueその「反対」に設定される(もう一度、それが何であれ)。このようにして、それが{1、0}、{-1、0}、{0、1}などであるかどうかを気にする必要はありません。また、それを 使用して作成されているため、比較で機能することが保証さています。
MestreLion、2015

3
@MestreLion:Cを知っている誰でもの数値を知っているfalseとしますtrue。Cを知らない人は、Cコードの想定読者ではありません。先ほど述べたように、Cには前のミレニアム以降、ブール型が組み込まれています。
キース・トンプソン、

12

_BoolC99のキーワードです。intまたはと同様に、タイプを指定しますdouble

6.5.2

2 _Bool型として宣言されたオブジェクトは、値0および1を格納するのに十分な大きさです。




1

stdbool.h マクロはtrueとfalseを定義していますが、1と0になるように定義されていることを覚えておいてください。

ですからsizeof(true)4です。


0

そのようなことはありません、おそらくintのマクロです


-1で
よかった

5
よく彼はC標準、例えば C90 を言う、私はそれがC99を含むと仮定する。
マットジョイナー、

2
彼はC90ではなくC90に特別に言及しているので、彼の意味するところだと思います。ウィキペディアによると、C99を完全にサポートするコンパイラはSun MicrosystemsのSun Studioだけです。さて、それは広く受け入れられている標準ではありませんか?間違いなく、ほとんどの最新のコンパイラーはC99標準の一部を実装しています。おそらく、あなたのような愚かなコメントを避けるために、私はそれについて言及しているはずです!このbtwでJavaまたはc#は何をしますか?
sindre j

8
標準C拡張(ISO C90など)は、特にC90自体ではなく、彼が興味を持っているC標準の種類を分類しています。これに対する適切な答えは、はい、そのようなC90、特にC99標準として標準Cは、ない実装boolタイプ。
マットジョイナー、

0

C99は、boolそのような目的のために意図されたユーザー定義型とコンパイラー拡張型を含み、一部のプログラムが "type-def"にbool

たとえばbool a = 0.1, b=2, c=255, d=256;、C99 boolタイプでは、4つのオブジェクトすべてが1に設定されます。C89プログラムが使用されたtypedef unsigned char bool場合、オブジェクトはそれぞれ0、1、255、0 を受け取ります。使用したchar場合、値は上記のようになるか、c-1になります。コンパイラー拡張機能bitまたは__bit型を使用した場合、結果はおそらく0、0、1、0(bitサイズ1の符号なしビットフィールド、または1つの値ビットを持つ符号なし整数型と同等の方法で処理される)になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.