stdbool.h在哪里?

27

我想在我的系统上找到 _Bool 的定义,以便在缺少该定义的系统上实现它。我在这里和其他网站上看到了各种定义,但是想要在系统上查找确定性的定义。

有一个小问题,就是我找不到 _Bool 或者 stdbool.h 的定义。

mussys@debmus:~$ find /usr/include/* -name stdbool.h
/usr/include/c++/4.3/tr1/stdbool.h

/usr/include/*/usr/include/*/* 上使用 grep 搜索 _Bool ,但没有找到。

那么它在哪里呢?

6个回答

17

_Bool 是一种内置类型,因此不要期望在头文件中找到它的定义,即使是系统头文件。

话虽如此,根据您正在搜索的路径猜测您的系统,您是否查看过 /usr/lib/gcc/*/*/include 目录?

我的“真正”的 stdbool.h 存放在那里。就像预期的那样,它将 bool 宏定义为 _Bool 。由于 _Bool 是编译器本地的一种类型,因此头文件中没有其定义。


谢谢。没有去检查过那里,不过我的系统是一样的,是的。 - James Morris

8

请注意:

_Bool 在 C99 中被定义。如果您使用以下命令构建程序:

gcc -std=c99

你可以期望它会在那里。

1
谢谢,但这不是我想问的。 - James Morris
1
我认为在C头文件中没有这样的功能可以定义。所有已存在的类型都是包装的,如果您将(无符号字符)布尔值(= 2)与另一个布尔值(= 3)进行比较,则它们不会匹配。因此true!= true,并且那可能很糟糕。同时bool b1 == true也可能失败。由于除了\ Bool之外的任何数据类型都没有这种行为,因此您可能无法自己创建它,因为它需要编译器后端支持,并且您无法重载运算符。您可以使用cmp_bool(bool b,bool b2),但这可能确实不是您想要的。我不能保证我是正确的,但我希望至少添加了一些内容。 :) - pbos
那是“下划线布尔”,格式出了问题,反斜杠下划线也没有帮助。 - pbos
1
我明白你的意思,但是为什么要将bool设置为2或3?请参见我在谷歌搜索“enum bool c”时找到的页面底部。http://www.lysator.liu.se/c/c-faq/c-8.html - James Morris
标准(第6.3.1.2节)规定:“1当任何标量值转换为_Bool时,如果该值与0相等,则结果为0;否则,结果为1。”。 - pmg
显示剩余3条评论

6
其他人已经回答了关于 _Bool 的问题和如何查找 C99 是否被声明的问题... 但是,我对每个人给出的自制声明并不满意。
为什么不完全定义这种类型呢?
typedef enum { false, true } bool;

我认为这已经有些过头了,因为我决定谷歌搜索“bool enum c”,然后被引导到http://www.lysator.liu.se/c/c-faq/c-8.html,可以查看页面底部关于将true定义为1的危险。 - James Morris
我同意你链接中提供的论点。就个人而言,为了清晰明了地分配给布尔变量,我会定义真和假。出于强类型背景的考虑,对我来说,布尔不是字符或整数,它是一种独立的类型,因此上面的枚举定义。此外,我认为从int到bool的自动转换并不是一个好主意(这适用于任何自动转换)。 - Adrien Plisson
1
如果头文件是从C++源文件中包含的呢?最好不要在定义类型时使用关键字“bool”、“true”和“false”。 - Michael Aaron Safyan
1
我们正在谈论C语言:C语言没有定义很多我们必须自己定义的概念。问题会出现在任何与C++关键字匹配的标识符上:static_cast,this等。 - Adrien Plisson
@AdrienPlisson 虽然这是正确的,但C++代码通常是使用C编写的库的客户端,因此不考虑任何在*.h文件中声明并可能被C++客户端使用的内容是愚蠢的(对于C源文件,您可以随心所欲而不必担心C++)。 - Michael Aaron Safyan
假设 OP 正在编写一个旨在由 C++ 消费的库,这样做是很愚蠢的,如果不是出于这个目的而编写代码,则应避免这样做。 - Dan Bechard

2

_Bool是C99中预定义的类型,类似于intdouble。你也不会在任何头文件中找到int的定义。

你可以做以下操作:

  • 检查编译器是否是C99
  • 如果是,使用_Bool
  • 否则使用其他类型(如intunsigned char

例如:

#if defined __STDC__ && defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
/* have a C99 compiler */
typedef _Bool boolean;
#else
/* do not have a C99 compiler */
typedef unsigned char boolean;
#endif

2
我没有预料到 #ifndef _Bool 会起作用,而且我使用的 gcc (4.3.2 debian) 也不支持。 - James Morris
1
出于二进制兼容性的原因,这可能不是一个看起来很好的主意。通常,在创建公共C API时,最好在需要布尔类型的地方简单地使用“int”。 - Michael Aaron Safyan
@MichaelAaronSafyan 不正确。通过 stdbool.h 定义 bool 是委员会推荐的针对现代 C 的方式。不建议使用 int 作为 bool。 - Alice
@Alice,我同意,那肯定是在自己的代码库中使用它的正确方式;然而,对于旨在在库外调用并且旨在成为API的函数,有时使用更有限的C子集来声明这些函数是有用的,以便允许更广泛的客户端能够使用它。话虽如此,这相当主观,我可以看到双方都有争议。 - Michael Aaron Safyan
编译器版本和操作系统/库版本之间有相当大的差异。即使您在现代编译器上编译了某些内容,仍可能存在符号需要通过dlsym或LoadLibrary动态加载的情况,或者您正在更新链接到其他人使用各种不同编译器或技术编译的库中的代码。你似乎把界面和实现搞混了。我并不建议您在实现(甚至在内部接口)方面限制自己,但是使超级兼容和稳定的界面也是有益的。 - Michael Aaron Safyan
显示剩余4条评论

2
一些编译器没有提供_Bool关键字,因此我编写了自己的stdbool.h文件:
#ifndef STDBOOL_H_
#define STDBOOL_H_

/**
 * stdbool.h
 * Author    - Yaping Xin
 * E-mail    - xinyp at live dot com
 * Date      - February 10, 2014
 * Copyright - You are free to use for any purpose except illegal acts
 * Warrenty  - None: don't blame me if it breaks something
 *
 * In ISO C99, stdbool.h is a standard header and _Bool is a keyword, but
 * some compilers don't offer these yet. This header file is an 
 * implementation of the stdbool.h header file.
 *
 */

#ifndef _Bool
typedef unsigned char _Bool;
#endif /* _Bool */

/**
 * Define the Boolean macros only if they are not already defined.
 */
#ifndef __bool_true_false_are_defined
#define bool _Bool
#define false 0 
#define true 1
#define __bool_true_false_are_defined 1
#endif /* __bool_true_false_are_defined */

#endif /* STDBOOL_H_ */

0
$ echo '_Bool a;' | gcc -c -x c -
$ echo $?
0

$ echo 'bool a;' | gcc -x c -c -
<stdin>:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘a’

这证明了_Bool是一个内置类型,而bool不是,通过编译一个没有包含任何头文件的单个变量声明。

$ echo '_Bool a;' | gcc -std=c99 -x c -c - $ echo $? 0 我明白。 - James Morris
也许现在有意义了,我解释了一些。 - Matt Joiner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接