bool是本机C类型吗?


265

我注意到Linux内核代码使用bool,但是我认为bool是C ++类型。bool是标准C扩展名(例如ISO C90)还是GCC扩展名?


2
comp.lang.c常见问题解答的第9节对此进行了讨论。
基思·汤普森


Linux内核使用-std=gnu89它来支持_BoolC90的扩展。“ include / linux / types.h”具有typedef _Bool bool;
伊恩·雅培

另外,Linux内核2.6.19 FWIW是第一个使用的版本typedef _Bool bool;(commit 6e21828743247270d09a86756a0c11702500dbfb),它需要GNU C 3.2或更高版本。
伊恩·雅培

Answers:


368

bool 当前C-C99中存在,但在C89 / 90中不存在。

在C99中,本机类型实际上称为_Boolbool而是在中定义的标准库宏stdbool.h(有望解析为_Bool)。类型的对象_Bool包含0或1,而truefalse也是来自的宏stdbool.h

注意,顺便说一句,这意味着C预处理器将解释#if true#if 0除非stdbool.h包含在内。同时,需要C ++预处理器才能本地识别true为语言文字。


62
2011年发布了新的ISO C标准(发布此答案后)。像往常一样,ANSI已采用ISO C11标准作为ANSI标准。由于历史原因,短语“ ANSI C”通常(但不恰当地)是指ANSI C89 / ISO C90标准定义的语言。由于C标准现在是由ISO首先发布的,并且由于存在三种ISO C标准且采用程度不同,因此最好参考该标准发布的年份(ISO C90,ISO C99,ISO C11),以避免混乱。
基思·汤普森

8
这是否意味着要_Bool占用1位内存?
Geremia'2

27
@Geremia:不,为什么?在C语言中,每个可寻址对象必须占用至少1个字节。在现实生活中,实现_Bool通常占用1个字节的内存。但是,语言规范明确允许使用_Bool位字段类型,这意味着通过使用位字段,您可以将_Bool值压缩为单个位(在较大的结构内)。
AnT

@AnT _Bool值如何既可以直接寻址(即大小为1字节)又可以参与位域?数组_Bool仍然需要其所有元素都是可寻址的(例如_Bool* ptr = &boolArray[123])。

118

C99添加了一个内置_Bool数据类型(有关详细信息,请参阅Wikipedia),如果您使用#include <stdbool.h>,它将bool作为宏提供给_Bool

您特别询问了Linux内核。它假定include的存在_Boolboolinclude / linux / types.h中提供typedef本身。


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却没有其中的大多数,而且可能永远不会...
Pavel Minaev 09年

5
发问者@Jonathan Leffler特别询问了ISO C90。:)实际上,通常当人们指的是ANSI C时,他们指的是C90。我不使用或不打算使用C99,我认为许多人也有同样的感觉。
2009年

6
@BobbyShaftoe:原始海报在评论中明确表示C90是一个例子。
基思·汤普森

32

C99在stdbool.h中具有它,但在C90中必须将其定义为typedef或枚举:

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类型的行为不同。例如,在C99 上将bool x=4294967296LL;bool x=0.1;设置x为1,但可能会将大多数typedef版本设置为零。
超级猫

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年的标准。)
Keith Thompson

9
@KeithThompson初始值可能是不必要的,但是此答案以非常优雅的方式选择了它们,而不是使用任意值,而是使用语言自己的语义并让编译器确定。
MestreLion,2015年

11
@MestreLion:语言本身的语义保证typedef enum { false, true } bool;可以完全按预期工作。1 == 0而且! false不优雅,只是被迷惑了。编译器没有决定权。它必须服从该语言定义的语义。
基思·汤普森

11
@KeithThompson:我不认为它们被混淆了,我想作者的意图是选择最“自然”的值:false设置为该语言表示不平等应该被评估为的任何值,并true设为其“相反”(再次,无论是什么)。这样一来,人们就不必在乎它是否为{1、0},{-1、0},{0、1}等,并且可以保证在比较中工作,因为它是 使用one 制作的
MestreLion

3
@MestreLion:任何了解C的人都知道false和的数值true。任何不了解C的人都不是C代码的预期读者。就像我说的那样,自上个千年以来,C就具有内置的布尔类型。
基思·汤普森

12

_Bool是C99中的关键字:它指定类型,就像int或一样double

6.5.2

2声明为_Bool类型的对象足够大,可以存储值0和1。




1

stdbool.h 定义了宏的true和false,但请记住将其定义为1和0。

这就是为什么sizeof(true)4。


0

没有这样的事情,可能只是int的宏


不错,为-1 ...问题是C90,我相信不是99
sindre j 2009年

5
好吧,他说C标准,例如 C90,我认为其中包括C99。
马特·乔纳

2
他特别提到C90,而不是C99,所以我认为他的意思是。根据维基百科,唯一完全支持C99的编译器是Sun Microsystems的Sun Studio。现在,这几乎不是一个广泛接受的标准吗?可以说,大多数现代编译器都实现了C99标准的某些部分,所以我应该提到过,以避免像您这样的愚蠢注释!这个btw与java或c#有什么关系?
sindre j

8
标准C扩展名(例如ISO C90)正在对他感兴趣的C标准类型进行分类,而不是对C90本身进行分类。对此的适当答案是,的,例如C90之类的C标准,特别是C99标准,确实实现了一种bool类型。
马特·乔纳

0

C99添加了一种bool类型,其语义与C之前几乎所有整数类型的语义都根本不同,包括为此目的而设计的用户定义类型和编译器扩展类型,并且某些程序可能对其进行了“类型定义”到bool

例如,给定bool a = 0.1, b=2, c=255, d=256;,则C99 bool类型会将所有四个对象设置为1。如果使用C89程序typedef unsigned char bool,则这些对象将分别接收0、1、255 和0。如果使用char,则值可能如上所述,或c可能为-1。如果它使用了编译器扩展名bit__bit类型,则结果可能为0、0、1、0(bit以等于大小为1的无符号位字段或具有一个值位的无符号整数类型的方式进行处理)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.