The New C: bool, Advice to C and C++ Programmers

新的C语言:布尔类型,对C和C++程序员的忠告

By Randy Meyers, May 01, 2002


True or False: The type bool behaves identically in C99 and C++. True or False: Your C89 bool hackery will survive unscathed under C99. Read and find out.

    真的还是假的:C99 和 C++ 中的布尔类型行为完全一致。真的还是假的:你在C89对布尔类型的骇客手段[a]能在C99中完好的存在。继续阅读并了解这些。

There is nothing new under the sun. As I wrote in my first installment of “The New C” [1], the C99 Standard contains almost nothing new. Except for two or three features, C99 standardized extensions from existing compilers. So, even if you are using a C compiler that has not been updated in several years, it might contain little pieces of C99. For example, variable length arrays [2, 3, 4, 5] came from the Cray C compiler, and a similar feature is in GNU C. Compound literals [6] and designated initializers [7] came from the Plan 9 C compiler. Lots of compilers have supported long long [8] for a long, long time. Restricted pointers [9] have been in compilers for high performance systems for years. The good news for programmers is that if you are using an old compiler that supports an extension that is now part of C99, you need not fear the portability consequences of using that extension quite so much.


    太阳底下无新事。就如我在第一期“新的C语言”中所写的,C99标准几乎没有包含新的东西。除了两个或三个特性以外,C99标准化了来自现存编译器的扩展。所以,即使即使你正在使用一个过去几年中都没更新过的C编译器,它也可能包含C99的一小部分。例如,变长数组 [2, 3, 4, 5] 来自 Cray 的C编译器,以及GNU C中一个类似的特性。复合字面量 [6] 和指定初始器 [7] 来自Plan 9 [b]的C编译器。许多编译器以及支持 long long [8] 很久很久了[c]。受限指针[9]已经在高性能系统中出现好几年了。 


There is another aspect of C99 that I find profound (but I am easily awed). There are at least two parts of C99 that any programmer can add to an older compiler simply by creating a header file. The first is the generalized integer support [10] in the C99 <stdint.h> and <inttypes.h> headers. The second is subject of this column, the bool type.


    C99还有我觉得很深刻的(但是我很容易就感到敬畏的)另一方面。C99中至少有两个部分,任何程序员都可以简单的创建一个头文件把它们加入一个老的编译器中。前者是C99 <stdint.h><inttypes.h> 头文件中的泛化整形支持。后者则是本专栏的主题,bool 类型。


The bool type came from C++. When I wrote that C99 standardized extensions from existing compilers, I was careful not to over qualify my statement by writing “existing C compilers.” C++ was the source of several features in C99 including mixed declarations and code and new lifetime and initialization rules [7]. The C99 committee felt strongly that the bool type in C99 should be compatible with C++ and should serve to broaden the intersection of the two languages. However, the C99 committee also had to introduce bool into C99 in such a way as to limit its impact on the existing C code base: moving even large programs from C90 to C99 should be nearly effortless. The C99 committee solved this problem by in effect making the new bool type conditional on whether a new header <stdbool.h> is included. The <stdbool.h> header may be included by C++, where it does nothing. This allows the same source code to be compiled either by C or C++, a particularly important feature when writing header files. Placing bool support in <stdbool.h> also allows programmers without access to C99 to create their own <stdbool.h> and get an approximation to the C99 and C++ feature.


    bool 类型来自C++。当我写下“C99标准化了来自现存编译器的扩展”时,我很小心地没有写下“现存的C编译器”而过分修饰我的陈述。C++是C99中几个新特性的来源,包括混合声明和语句、新的生存期、以及初始化规则 [7]。C99委员会强烈地认为,C99的 bool 类型应该与C++的兼容,以扩大这两种语言的交集。然而,C99委员会为C99引入 bool 时,还以基于现存的C代码这种方式限制它的影响:即使把大程序从C90迁移到C99也应该是毫不费力的。C99委员会解决了这个问题,通过以是否包含新的头文件 <stdbool.h>为条件,使新的 bool 类型起作用。<stdbool.h> 头文件也可以被C++包含,其中它什么都不做。编写头文件时一个特别重要的特点是,允许同样的源代码被C或C++编译。在 <stdbool.h> 中放入对 bool 的支持还允许程序员不使用C99就能创建他们自己的 <stdbool.h>,并且得到近似于C99和C++的特性。


In this column, I am going to discuss the bool type in C99 and describe how to write your own <stdbool.h> if you do not have access to C99.


    本专栏中,我将要讨论C99中的 bool 类型,并叙述如何编写你自己的 <stdbool.h>, 如果你还没有使用C99的话。

Compatibility with Old Code

与旧代码的兼容性

Strictly speaking, there is no functional need for the bool type. Any program that needs a flag can use an int instead. However, even with the crummy variable name, the declaration bool x; communicates a great deal of information to the programmer about the purpose of variable x and how variable x is likely to be used in expressions. Likewise, the expression y = true; communicates information lacking in the computationally equivalent y = 1;. Not surprisingly, many C programmers have their own homegrown version of bool to increase the expressiveness of their programs.


    严格来说,没有任何功能需要 bool 类型。任何需要标志的程序都可以使用 int 来代替。然而,即使是相当简单的变量名,声明 bool x,也向程序员传达了大量的信息,关于变量 x 的目的以及 x 在表达式中可能的用法。同样的表达式 y = true,传达了与之等价的 y = 1 所缺乏的信息。毫不奇怪,许多C程序员拥有他们自制的 bool 版本来提升他们程序的表达性。


C99 followed C++’s lead and added the type bool and the two boolean constants true and false. In C++, bool, true, and false are keywords in the language. This is a reasonable approach given the pervasive use of overloading involving bool in C++ and its library. However, it does mean that C programs using homegrown bool being ported to C++ frequently encounter compilation errors due to the C++ keywords. Worse, if the homegrown bool uses macros, the C program may hijack the C++ type system causing overloading and the C++ library to malfunction.


    C99跟随C++的指引加入了 bool 类型以及两个布尔常量 true false。在C++中,booltrue、以及 false 是语言的关键字。这是一种合理的做法,因为C++及其函数库中无处不在地使用涉及 bool 的重载。然而,这确实表示使用自制 bool 的C程序移植到C++时会频繁地遇到编译错误,因为它是C++的关键字。更糟糕的是,如果自制的 bool 使用了宏,该C程序可能劫持了C++的类型系统,导致重载并使C++函数库失灵。


C99 lacks user overloading, and bool is not used throughout the C library. Thus, C99 has few problems coexisting with a homegrown bool. To avoid invalidating homegrown versions of bool, C99 declares bool, true, and false as macros in the header <stdbool.h>. If <stdbool.h> is not included, the program can ignore the new boolean type in C99 and can use the names bool, true, and false in any way it pleases. Even when <stdbool.h> is included, there are some provisions for accommodating a homegrown bool (discussed below).


    C99缺乏用户重载,并且在C函数库中没有到处使用 bool。因此,C99在与自制的 bool 并存上几乎没什么问题。为了避免使自制版本的 bool 类型失效,C99 在头文件 <stdbool.h> 中把 booltrue、以及false作为宏来声明。如果没有包含 <stdbool.h>,程序可以忽略C99的新布尔类型,并以任何它想要的方式来使用 booltrue、以及false的名称。即使包含了 <stdbool.h> 也会有一些预防措施来迁就自制的 bool (在下文讨论)。


C99 does add one new keyword: _Bool. This is the boolean type built into the C99 compiler. The bool macro in <stdbool.h> merely expands into _Bool. Note that since 1989 the C Standard has reserved all identifiers beginning with an underscore followed by either another underscore or a capital letter. So, the _Bool keyword should not interfere with existing code. Note also that the intended way to use the boolean type in C99 is to include <stdbool.h> and use bool. Not only is bool more tasteful and easier to type, it is also compatible with C++. Never use the _Bool keyword directly.

   

    C99确实增加了一个新的关键字:_Bool。这是内建于C99编译器的布尔类型。<stdbool.h> 中的 bool 宏就是简单地扩展成 _Bool 。注意,自动1989年起C标准就保留了所有以下划线后面跟随另一个下划线或者大写字母开头的标识符。还要注意,使用C99布尔类型建议的方法是包含 <stdbool.h> 并使用 boolbool 不仅更雅致更容易输入,它还与C++兼容。绝不要直接使用 _Bool 关键字。

The Boolean Type

Unless I specifically write otherwise, C and C++ have the same semantics for bool.


    除非我特别书明,否则C和C++的 bool 有相同的语义。


The bool type only holds the values true and false. While this requirement only necessitates a single bit of storage, sizeof still needs to return an integral value for sizeof(bool), and you can take the address of a bool using the & operator. Thus, bool must take up at least a byte of storage, but both C and C++ allow the compiler to use more than one byte. For example, some compiler might make sizeof(bool) equal sizeof(int).


    bool 类型只能保存 true false 的值。虽然这个要求只需要一个单独位的存储空间,对于 sizeof(bool)sizeof 仍然需要返回一个整体的值,并且你可以使用 & 运算符取一个 bool 的地址。因此,bool 必须至少占一个字节的存储空间。但是C和C++都允许编译器使用一个字节以上。例如,一些编译器可能会让 sizeof(bool) 等于 sizeof(int)


The bool type is considered to be a member of the integer family of types. Thus, an expression of type bool can be used wherever an expression of type int can be used. (C++ makes an exception for the ++ and - operators). When a numeric value is needed for a value of type bool, the bool automatically promotes to int. If the bool value is true, its value becomes 1. If the bool value is false, its value becomes 0.


    bool 类型被当作是整型家族类型的一个成员。因此,一个 bool 类型的表达式可以用于任何可以使用 int 类型的表达式(C++对 ++ 和 - 运算符有一个例外)。 当需要 bool 类型值的数值时,bool 自动提升为 int。如果 bool 值是 true,它的值变成 1 。如果 bool 值是 false,它的值变成 0


Arithmetic types and pointer types may be converted to bool. However, this is not the normal conversion to an integer type. A conversion to bool converts the value to true or false the same way that the if statement determines whether its controlling expression is true or false: it implicitly compares the value against zero. Thus,


    算术类型和指针类型可以转换成 bool。然而,这不是通常的到整型的转换。到 bool 的转换把值转换为 true 或 false 的方式跟 if 语句决定它的控制表达式为 true 或 false 的方式相同:它隐式地把这个值跟零比较。因此:

void ex1(char c, int i, double d, char *p)

{
    bool b1 = c;
    bool b2 = i;
    bool b3 = d;
    bool b4 = p;
}
is compiled exactly as if it had been written:

编译成就像它就是这样写的:
void ex1(char c, int i, double d, char *p)
{
    bool b1 = c != '\0';
    bool b2 = i != 0;
    bool b3 = d != 0.0;
    bool b4 = p != NULL;
}

The conversion to bool works the same regardless of whether it is an explicit or an implicit conversion. Thus, all legitimate ways of getting a value into a bool result in the bool being either true or false, 1 or 0. If the bool is uninitialized or has received a value through some invalid method (assignment through the wrong member of a union or via a mistyped pointer), the program has undefined behavior if it tries to use the value of the bool. Whether such a “bad” bool is either true or false is undefined.


    不管是隐式还是显式转换,到 bool 的转换都以相同的方式工作。因此,所有合法的方式让一个值存入一个 bool ,结果 bool 要么是 true 要么是 false,要么是 1 要么是 0。如果 bool 是未初始化的或是通过一些无效的方法得到一个值(通过一个错误的联合成员赋值或是通过一个错误类型的指针),如果程序尝试使用这个 bool 的值,它会得到未定义的行为。这样一个既不是 true 又不是 false 的“坏” bool 是未定义的。


The two boolean constants are true and false, which have the numeric values 1 and 0, respectively. In C99, these constants have type int. In C++, they have type bool. A very minor incompatibility between C99 and C++ is that sizeof(bool) might not equal sizeof(true) in C99. In C99, true and false are just macros that expand to 1 and 0, respectively.


    两个布尔常量是 true false,它们的值分别是 1 0。在C99种,这些常量的类型为 int。在C++中,它们的类型为 bool。在C99和C++之间一个很小的不兼容是 C99 中 sizeof(bool) 可能不等于 sizeof(true)。在C99中,ture false 只是分别扩展成 10 的宏。


true and false may be used in the controlling expressions of preprocessor #if directives. While this is part of both C99 and C++, I’ve encountered a few C++ compilers that issue errors about this. Also beware: a standard feature of the preprocessor is that any identifiers used in the controlling expression of #if that are not defined to be macros are replaced with the constant 0. Thus, a preprocessor may consider true to be 0 (false) if <stdbool.h> is not included when compiling C99. This problem can also occur when compiling C++ if the preprocessor has not been updated to understand true and false for C++.


    true false 可以在预处理器 #if  指令的控制表达式中使用。虽然这是C99和C++的一部分,我还是遇到一些C++编译器对此报错。还要注意:预处理器的一个标准特性是,#if 表达式的控制语句中使用的任何没有定义成宏的标识符都会被替换成常量 0。因此,预处理可以把 true 当作 0 (false)如果在编译C99的时候没有包含 <stdbool.h> 。这个问题还会在编译C++时出现,如果预处理器还没有升级到能理解C++的 true false


Bitfield members may have type bool. A bool bitfield never sign extends. Thus, if you store 1 in a one-bit bool bitfield, the value of that bitfield will be 1 (a clean true) and never -1. For this reason, C99 considers bool to be an unsigned type. C++ requires this semantics for bool bitfields, but does not explicitly say bools are unsigned.


    位段成员可以使用 bool 类型。一个 bool 的位段绝不会进行符号扩展。因此,如果你在一个一位的 bool 位段上存储 1,该位段的值将会是 1 (一个干净的 true)并且绝不会是 -1 。出于这个理由,C99把 bool 当作无符号类型。C++需要这个 bool 位段的语义,但是没有明确说明 bool 是无符号的。


The behavior of bools in expressions follows from the rules above. Interesting cases are the ++ and -- operators. ++ adds one to its operand. If the operand is a bool, its value is converted to an int in order to perform the operation, and then the result is converted back to a bool to be stored. Thus, if you increment a bool whose value is false, you add 1 to zero getting one, which converts back to true. If you increment a bool whose value is true, you add 1 to one getting two, which converts back to true. Thus, incrementing a bool always sets its value to true. Likewise, decrementing a bool sets the bool to its logically complemented value (think it through). C++ allows incrementing a bool (but marks the feature as deprecated, which means it might be removed in a future standard). C++ forbids decrementing a bool. C99 allows both.


    表达式中 bool 的行为遵循上述的规则。有趣的情况是 ++ 和 -- 运算符。++ 对它的操作数加以。如果操作数是一个 bool,它的值要转换成 int 来进行这个操作,然后这个结果要转换回 bool 来存储。因此,如果你递增一个值为 false bool,你给零加 1 得到一,它将转换回 true。如果你递增一个值为 true bool ,你对一加 1 得到二,它将转换回 true。因此对 bool 的递增总是把它的值设置为 true。同样的,对一个 bool 的递减把这个 bool 设置成它逻辑上的补码值(好好地思考它)。C++允许对 bool 的递增(但是把这个特性标记为弃用的,这表示它可能会在将来的标准中移出)。C++禁止对 bool 的递减。C99两者都允许。

<stdbool.h> Coexistence

<stdbool.h> 共存

In addition to defining macros for bool, true, and false, <stdbool.h> defines the macro __bool_true_false_are_defined to be 1. This warns a homegrown version of bool that <stddef.h> has been included and has defined macros for bool, true, and false.


    除了定义 booltrue、以及 false 的宏以外,<stdbool.h> 还定义 __bool_true_false_are_defined1。这警告自制版本 bool:已经包含了 <stddef.h> 并且已经定义了 booltrue、以及 false 的宏。


The homegrown version of bool might check __bool_true_false_are_defined and not define its own versions of bool, true, and false. This might be useful if the homegrown bool is in a project-wide header file that is included everywhere, but a few modules have been converted to use the C99 version of bool.


    自制版本的 bool 可能会检查 __bool_true_false_are_defined  并且不定义自己版本的 booltrue、以及 false。如果自制德 bool 是在一个广阔项目的到处都被包含的头文件中,但是其中一些模块已经转换到使用C99版本的 bool 时,这是非常有用的。


The homegrown version of bool might also check __bool_true_false_are_defined in order to undefine the macros from <stdbool.h>. Normally, it is undefined behavior to undefine a macro from a standard header. However, C99 permits bool, true, and false from <stdbool.h> to be undefined and possibly redefined to something else. This is considered a short-term concession to coexistence with homegrown versions of bool. The feature is marked obsolescent, and the next version of C99 may withdraw this permission.


    自制版本的 bool 可能还会检查 __bool_true_false_are_defined 来取消 <stdbool.h> 中的宏定义。通常来说,取消标准头文件中的宏定义是一个未定义兴we。然而,C99允许取消 <stdbool.h>booltrue、以及 false 的定义并且可能重定义成别的东西。这是考虑到短期内与自制版本 bool 共存而作出的让步。这个特性被标记为逐步废弃的,C99的下一个版本可能会撤消这个许可。

Roll Your Own <stdbool.h>

编写你自己的 <stdbool.h>

Although you cannot fully add bool to a pre-C99 compiler merely by writing a header file, you can come close. The only thing lacking is that conversions to your own bool will not have the proper semantics of testing the value being converted against zero. If you write such comparisons explicitly, you can write your own version of <stdbool.h> and program portably between C90, C99, and C++.


    尽管你不能仅仅编写一个头文件就把 bool 添加到一个C99以前的编译器,你也很接近了。唯一缺乏的是,你自己的 bool 没有合适的语义与零比较测试这个值。如果你显示地写出这些比较,你可以编译你自己版本的能够在C90、C99和C++之间移植的 <stdbool.h> 和程序。


Listing 1 shows my version of <stdbool.h>. Note that no macros are defined if the header is included from C++ in order to not interfere with C++’s built-in bool. If the file is compiled by C99, bool is defined to be _Bool as required by the C99 Standard. If included from pre-C99, bool is defined to be an unsigned type suitable for use as a bitfield. By making the type unsigned, bitfields of length 1 will not sign extend and thus meet the requirements of C99 and C++. Not all compilers permit unsigned char bitfields, but it is a popular extension. If your compiler complains, define bool to be unsigned int.

   

    Listing 1 展示了我自己版本的 <stdbool.h>。注意,如果该头文件被C++包含,它不会定义任何宏,以免妨碍到C++的内建 bool。如果文件被C99编译,为了满足C99标准的要求,bool 被定义为 _Bool。如果被C99以前的编译器包含,bool 被定义为使用于位段的无符号类型。把这个类型定义为无符号的,长度为1的位段将不会进行符号扩展,因而满足了C99和C++的要求。不是所有的编译器都允许 unsigned char 的位段,但这是一个流行的扩展。如果你的编译器抱怨这个,把 bool 定义为 unsigned int。


Listing 2 is a short test program that checks our version of <stdbool.h>. The program can be run under C90, C99, or C++. Note that stdbool.h is included using the quoted form of the directive. This allows the compiler to find our stdbool.h even though it is not located with the system includes. If an official C99 version becomes available, merely deleting our own file will cause the compiler to find the system version since the quoted #include searches the system area if it cannot find the header in the user area. Some compilers have options to allow additional directories to be searched when the <> form of #include is used. Under such a compiler, #include <stdbool.h> would work.


    Listing 2 是一个检查我们版本 <stdbool.h> 的短小测试程序。该程序可以在C90、C99或C++下运行。注意 stdbool.h 是以引号形式的指令包含的。这让编译器能够找到我们的  stdbool.h 即使它不位于系统的 include。如果有一个正式的C99版本可以用,简单的删除我们的文件就能让编译器找到系统的版本,因为引号的#include 无法在用户区域找到该头文件时就在系统区域搜索。一些编译器有一个选项,允许在使用 <> 形式的 #include 时搜索附加的目录。在这样的编译器中,#include <stdbool.h> 也能工作。


C99 and C++ should pass the test in Listing 2 without any warnings from the test program run. A few C++ compilers will issue compile-time warnings about the implicit conversions to bool and perhaps using bool with a relational operator. These operations are valid C++, but sometimes misused, and so the compilers are trying to be helpful. A pre-C99 compiler should only get one warning that the conversion to bool does not compare against zero.


    C99 和 C++ 在程序运行时应该不发出任何警告就能通过 Listing 2 的测试。一些C++编译器会 对 隐式转换为 bool 并可能对 bool 使用关系运算符发出编译时警告。这些运算符在C++中是有效的,但是一些时候被错误使用了,所以这些编译器尝试对此有所帮助。一个C99以前的编译器应该只得到一个警告:bool 的转换没有跟零比较(conversion to bool does not compare against 0)。


One popular C++ compiler issues errors and fails to compile the #if directives that test whether true and false can be used in the preprocessor. If you encounter this compiler bug, feel free to delete or comment out the tests.


    一个流行的C++编译器发出错误,并且无法编译用来测试 true 和 false 是否可以在预处理器中使用的 #if 指令。如果你碰到了这个编译器 bug,随意地删除或是注释掉这个测试就可以了。

Conclusion

总结

C99 makes programs more readable and increases the overlap between C and C++ by adding the bool type. Programs using bool can be compiled under either C99 or C++ by including <stdbool.h>, and by defining bool, true, and false in <stdbool.h>, C99 avoids keyword problems that might trouble old C code. Pre-C99 programmers or even C++ programmers writing source to be shared with C can write their own version of <stdbool.h> without waiting for a C99 implementation to be available.


    C99加入 bool 类型使程序更可读,并且增加了C和C++的交际。使用 bool 的程序可以由C99或C++编译,通过包含 <stdbool.h> 及其中定义的booltrue、以及 false,C99避免了可能会困扰到旧的C代码的关键字问题。C99以前的程序员甚至是C++程序员都可以编写他们自己版本的 <stdbool.h> 源文件跟C共享,而不需要等待一个C99实现可用。

References

[1] Randy Meyers. “The New C,” C/C++ Users Journal, October 2000.

[2] Randy Meyers. “The New C: Why Variable Length Arrays,” C/C++ Users Journal, October 2001.

[3] Randy Meyers. “The New C: Variable Length Arrays, Part 2,” C/C++ Users Journal, December 2001.

[4] Randy Meyers. “The New C: Variable Length Arrays, Part 3: Pointers and Parameters,” C/C++ Users Journal, January 2002.

[5] Randy Meyers. “The New C: Variable Length Arrays, Part 4: VLA typedefs and Flexible Array Members,” C/C++ Users Journal, March 2002.

[6] Randy Meyers. “The New C: Compound Literals,” C/C++ Users Journal, June 2001.

[7] Randy Meyers. “The New C: Declarations and Initializations,” C/C++ Users Journal, April 2001.

[8] Randy Meyers. “The New C: Integers in C99, Part 1,” C/C++ Users Journal, December 2000.

[9] Randy Meyers. “The New C: Restricted Pointers,” C/C++ Users Journal, November 2000.

[10] Randy Meyers. “The New C: Integers, Part 3,” C/C++ Users Journal, February 2001.

Randy Meyers is a consultant providing training and mentoring in C, C++, and Java. He is the current chair of J11, the ANSI C committee, and previously was a member of J16 (ANSI C++) and the ISO Java Study Group. He worked on compilers for Digital Equipment Corporation for 16 years and was Project Architect for DEC C and C++. He can be reached at rmeyers@ix.netcom.com.

注释

[a] 不要一味相信字典,字典中的hackery是“印度牛车”。而这个地方,这应该是一个跟“hacker”有关的单词,我翻译成“骇客手段”也许并不是准确的。在C89中不存在布尔类型,需要一些手段来实现。

[b] http://plan9.bell-labs.com/plan9/

[c] 这句话的原文很有意思:Lots of compilers have supported long long for a long, long time。



Listing 1: My version of <stdbool.h>

/* An interim version of <stdbool.h> from C/C++ Users Journal
* May 2002. This file may be included from C90, C++, or C99
* (but C99 should come with its own version).
*/
/* 一个来自 C/C++用户期刊2002年五月号的临时版本 <stdbool.h>
 * 该文件可以被C90、C++或C99包含(但是C99应该使用它自带的版本)。
 */

/* If C++, do nothing since bool is built in */
/* 如果是C++,什么也不做,因为 bool 已经内建 */
#if !defined(__cplusplus)

# if !defined(__bool_true_false_are_defined)
# define __bool_true_false_are_defined 1

/* If this is C99 or later, use built-in bool */
/* 如果是C99或以后版本,使用内建的 bool */
# if __STDC_VERSION__ >= 199901L
# define bool _Bool
# else
/* Choose an unsigned type that can be used as a bitfield */
/*  选择一个可以用作位段的无符号类型 */
# define bool unsigned char
# endif

# define true 1
# define false 0
# endif

#endif /* !defined(__cplusplus) */

— End of Listing —


Listing 2: Test program for <stdbool.h>

/* Test program for <stdbool.h>. May be compiled by C90, C99, or C++.
*/
/* <stdbool.h> 的测试程序。可以被C90、C99或C++编译 */
#include <stdio.h>
#include "stdbool.h"

struct S {
    bool b : 1;
};

int main()
{
    bool b;
    struct S s;

    if (true != 1)
        printf("warning: true does not have integer value 1\n");

    if (false != 0)

        printf("warning: false does not have integer value 0\n");

    b = 2;
    if (b != 1)
    printf("warning: conversion to bool does not compare "
        "against 0\n");

    b = -1;
    if (b < 0L)
        printf("warning: bool is not unsigned\n");

    s.b = true;
    if ((int) s.b != true)
        printf("warning: bool bitfield does not cleanly hold true\n");

    /* Some compilers mistakenly issue an error for the next line */
    /* 一些编译器错误地对下一行发出错误诊断 */
#if !true
    printf("warning: true did not work in #if\n");
#endif

    /* Some compilers mistakenly issue an error for the next line */
    /* 一些编译器错误地对下一行发出错误诊断 */
#if false
    printf("warning: false did not work in #if\n");
#endif

#ifdef __bool_true_false_are_defined
    printf("note: __bool_true_false_are_defined is defined "
        "with value %d\n", __bool_true_false_are_defined);
#else
    printf("note: __bool_true_false_are_defined is not defined\n");
#endif

    printf("note: sizeof(bool) is %u bytes\n",
        (unsigned int) sizeof(bool));

    return 0;
}
— End of Listing —


http://www.drdobbs.com/cpp/184401520