bool 是原生 C 类型吗?
Posted
技术标签:
【中文标题】bool 是原生 C 类型吗?【英文标题】:Is bool a native C type? 【发布时间】:2010-12-09 03:53:50 【问题描述】:我注意到 Linux 内核代码使用 bool,但我认为 bool 是 C++ 类型。 bool 是标准 C 扩展(例如 ISO C90)还是 GCC 扩展?
【问题讨论】:
comp.lang.c FAQ 的第 9 节讨论了这一点。 直接链接:c-faq.com/bool/index.html Linux 内核使用-std=gnu89
支持_Bool
作为C90 的扩展。 “include/linux/types.h”有typedef _Bool bool;
。
另外,FWIW,Linux 内核 2.6.19 是第一个使用 typedef _Bool bool;
(提交 6e21828743247270d09a86756a0c11702500dbfb)的版本,它需要 GNU C 3.2 或更高版本。
【参考方案1】:
bool
存在于当前的 C - C99 中,但不存在于 C89/90 中。
在 C99 中,本机类型实际上称为 _Bool
,而 bool
是在 stdbool.h
中定义的标准库宏(预期解析为 _Bool
)。 _Bool
类型的对象包含 0 或 1,而 true
和 false
也是来自 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 的行为将不同于 C99bool
的行为,也不同于许多编译器的 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的人都知道false
和true
的数值。任何不懂 C 的人都不是 C 代码的预期受众。正如我所说,自上个千年以来,C 就有一个内置的布尔类型。【参考方案6】:
_Bool
是 C99 中的关键字:它指定类型,就像 int
或 double
。
6.5.2
2 声明为 _Bool 类型的对象 足够大以存储值 0 和 1.
【讨论】:
【参考方案7】:C99 在 stdbool.h
中定义了 bool、true
和 false
。
【讨论】:
【参考方案8】:stdbool.h
定义了宏 true
和 false
,但请记住它们被定义为 1 和 0。
这就是为什么sizeof(true)
等于sizeof(int)
,对于 32 位架构来说是 4。
【讨论】:
【参考方案9】:stdbool.h是在c99中引入的
【讨论】:
【参考方案10】: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
,或一个值位的无符号整数类型)。
【讨论】:
【参考方案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
类型。以上是关于bool 是原生 C 类型吗?的主要内容,如果未能解决你的问题,请参考以下文章