【问题标题】:Is bool a native C type?bool 是原生 C 类型吗?
【发布时间】:2010-12-09 03:53:50
【问题描述】:

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

【问题讨论】:

标签: c gcc linux-kernel boolean


【解决方案1】:

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

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

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

【讨论】:

  • 有一个新的 ISO C 标准,于 2011 年发布(发布此答案后)。 ANSI 像往常一样采用 ISO C11 标准作为 ANSI 标准。由于历史原因,短语“ANSI C”通常(但不正确地)指的是由 ANSI C89 / ISO C90 标准定义的语言。由于 C 标准现在首先由 ISO 发布,并且由于已经存在三个 ISO C 标准,采用程度不同,因此最好参考标准发布的年份(ISO C90、ISO C99、ISO C11)以避免任何混乱。
  • 这是否意味着_Bool 占用了 1 位内存?
  • @Geremia:不,为什么?在 C 中,每个可寻址对象必须至少占用 1 个字节。而在现实生活中的实现_Bool 通常占用 1 个字节的内存。但是,语言规范明确允许使用_Bool 作为位域类型,这意味着通过使用位域,您可以将_Bool 值压缩到单个位中(在更大的结构中)。
  • @AnT _Bool 值如何既可以直接寻址(即大小为 1 字节)又可以参与位域? _Bool 的数组仍然需要其所有元素都是可寻址的(例如 _Bool* ptr = &boolArray[123])。
  • @Dai 您的言论应该是一个完全独立的 SO 问题。
【解决方案2】:

C99 增加了一个内置的_Bool 数据类型(详见Wikipedia),如果你#include <stdbool.h>,它提供bool 作为_Bool 的宏。

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

【讨论】:

  • 至于为什么,是允许它在定义可能与遗留代码冲突的地方不被定义和重新定义。
【解决方案3】:

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) { ... }

【讨论】:

  • 请注意 typedef 的行为将不同于 C99 bool 的行为,也不同于许多编译器的 bit 类型。例如,bool x=4294967296LL;bool x=0.1; 在 C99 上会将 x 设置为 1,但可能会将大多数 typedef 版本设置为零。
【解决方案4】:

不,ISO C90 中没有bool

这是标准 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 与 C 的一些其他差异:http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html

【讨论】:

  • 出于实际目的,只要仍然没有像样的编译器支持,这真的很重要吗?甚至 gcc 直到最近才拥有 C99 的一半功能,而 MSVC 也没有大部分功能,而且可能永远不会......
  • @Jonathan Leffler,提问者专门询问了 ISO C90。 :) 事实上,通常当人们提到 ANSI C 时,他们都指的是 C90。我不使用或真的打算使用 C99,我想很多人都有同样的感觉。
  • @BobbyShaftoe:原发帖人在评论中明确表示C90就是一个例子。
【解决方案5】:
/* 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. */

【讨论】:

  • 初始值完全没有必要。 typedef enum { false, true }; 一样好。如果您坚持更明确,可以写typedef enum { false = 0, true = 1 };。 (或者如果您的编译器支持它,则只需 #include <stdbool.h>;它已成为标准 14 年。)
  • @KeithThompson 初始值可能是不必要的,但这个答案以一种非常优雅的方式选择它们,不是使用任意值,而是使用语言自己的语义并让编译器决定。
  • @MestreLion:语言自身的语义保证typedef enum { false, true } bool; 完全按预期工作。 1 == 0! false 并不优雅,它们只是被混淆了。编译器无需做出任何决定;它必须遵守语言定义的语义。
  • @KeithThompson:我不认为它们被混淆了,我猜作者的意图是选择最“自然”的值:false 设置为语言所说的不等式应该的任何值被评估为,并将true 评估为它的“对立面”(同样,不管那是什么)。这种方式不应该关心它是否是 {1, 0}, {-1, 0}, {0, 1} 等,并且它可以保证在比较中起作用,因为它是精心设计的使用一个。
  • @MestreLion:懂 C 的人都知道falsetrue 的数值。任何不懂 C 的人都不是 C 代码的预期受众。正如我所说,自上个千年以来,C 就有一个内置的布尔类型。
【解决方案6】:

_Bool 是 C99 中的关键字:它指定类型,就像 intdouble

6.5.2

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

【讨论】:

    【解决方案7】:

    C99 在 stdbool.h 中定义了 bool、truefalse

    【讨论】:

      【解决方案8】:

      stdbool.h在c99中引入

      【讨论】:

        【解决方案9】:

        C99 添加了一个 bool 类型,其语义与之前在 C 中存在的几乎所有整数类型的语义根本不同,包括用于此类目的的用户定义和编译器扩展类型,并且某些程序可能具有“type-def”编辑为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(以等同于大小为 1 的无符号位域的方式处理 bit,或一个值位的无符号整数类型)。

        【讨论】:

          【解决方案10】:

          stdbool.h 定义了宏 truefalse,但请记住它们被定义为 1 和 0。

          这就是为什么sizeof(true) 等于sizeof(int),对于 32 位架构来说是 4。

          【讨论】:

            【解决方案11】:

            没有这样的东西,可能只是 int 的宏

            【讨论】:

            • -1 很好...问题是 C90,我相信不是 99
            • 好吧,他说的是 C 标准 eg C90,我假设包括 C99。
            • 他特别提到了 C90,而不是 C99,所以我假设他的意思。根据维基百科,唯一完全支持 C99 的编译器是 Sun Microsystems 的 Sun Studio。现在,这几乎不是一个被广泛接受的标准,是吗?可以说,大多数现代编译器都实现了 C99 标准的部分内容,我可能应该提到这一点,以避免像你这样愚蠢的 cmets!顺便说一句,java 或 c# 有什么用?
            • 标准 C 扩展(例如 ISO C90) 正在对他感兴趣的 C 标准类型进行分类,而不是专门对 C90 本身进行分类。对此的适当回答是,一个 C 标准,例如 C90,特别是 C99 标准,确实实现了 bool 类型。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-01-16
            • 2019-05-05
            • 2015-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-08
            相关资源
            最近更新 更多