0%

BOOL 和 bool(C++ 的) 和 _Bool(C 的)

2016年1月12日 18:14:37

本节转自 bool BOOL 和 _Bool辨析

布尔类型

BOOL 类型在头文件 <windef.h> 中定义为 typedef int BOOL;在头文件 <wtypes.h> 中定义为 typedef long BOOL

BOOL 类型,即 int 类型的长度视实际环境来定,一般可认为是 4 个字节。

BOOL 是微软定义的表达布尔逻辑的类型。与 C++ 中的 bool 类型不同是,它是一个三值逻辑:TRUE、FALSE 和 ERROR。当返回值为大于 0 的整数时为 TRUE,返回值为 0 时为 FALSE,返回值为 -1 时为 ERROR。

bool 类型在 C++ 中以关键字的形式被支持,表示布尔类型,其对应变量的值只有真(true)和假(false)两种值。bool 在 C++ 里占用 1 字节。

_Bool 是 C99 标准中定义的一个新关键字,以提供布尔类型。C2008 草案中只规定了 _Bool 类型的大小至少应能够存放 0 和 1 这两个值。而并没有规定具体的大小。这交给编译器自由发挥了。

以上,足够读者区别彼此的使用场景了。

使用

在 C 代码中使用布尔类型的几种方式:(如果编译器不支持 C99,就只能使用第一种方法了)

自己定义的“仿布尔类型”

在 C99 标准被支持之前,我们常常自己模仿定义布尔类型,方式有很多种,常见的有下面两种:

1
2
3
4
5
6
7
8
/* 第一种方法 */

typedef int BOOL;
#define TRUE 1
#define FALSE 0
/* 第二种方法 */

enum bool{false, true};

使用 C99 新增的关键字 _Bool

标准并未对 _Bool 规定具体的大小。我们使用 gcc(64位环境)做下面测试:

测试结果

看来,gcc 编译器规定 _Bool 类型的长度为 1,只能取值为 0 或 1 。将任意非零值赋值给 _Bool 类型变量,都会先转换为 1,表示为真;将零值赋值给 _Bool 类型,结果为 0,表示为假。

使用 C99 新增头文件 stdbool.h

在 C++ 中,通过 bool 来定义布尔变量,通过 true 和 false 对布尔变量进行赋值。C99 为了让我们能够写出与 C++ 兼容的代码(在 c 代码中使用 bool、true、false,而非在C++ 代码中使用 _Bool),添加了头文件 <stdbool.h> 。所以我们只要包含了该头文件,就可以像 C++ 中使用布尔变量的方式进行操作。

在我自己的 linux 系统中查找 stdbool.h 头文件,找到两处:

系统定义

1
[root@Betty ~]# vi /usr/lib/syslinux/com32/include/stdbool.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
* $Id: stdbool.h,v 1.1 2003/04/16 06:32:31 hpa Exp $
*
* stdbool.h
*/

#ifndef _STDBOOL_H
#define _STDBOOL_H

#ifndef __cplusplus

#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
# if !defined(__GNUC__) ||(__GNUC__ < 3)
typedef char _Bool; /* For C compilers without _Bool */
# endif
#endif

#define bool _Bool
#define true 1
#define false 0

#else

/* C++ */
#define bool bool
#define true true
#define false false

#endif

#define __bool_true_false_are_defined 1

#endif /* _STDBOOL_H */

GCC 定义

1
[root@Betty ~]# vi /usr/lib/gcc/x86_64-redhat-linux/4.1.1/include/stdbool.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */

/* As a special exception, if you include this header file into source
files compiled by GCC, this header file does not by itself cause
the resulting executable to be covered by the GNU General Public
License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General
Public License. */

/*
* ISO C Standard: 7.16 Boolean type and values <stdbool.h>
*/

#ifndef _STDBOOL_H
#define _STDBOOL_H

#ifndef __cplusplus

#define bool _Bool
#define true 1
#define false 0

#else /* __cplusplus */

/* Supporting <stdbool.h> in C++ is a GCC extension. */
#define _Bool bool
#define bool bool
#define false false
#define true true

#endif /* __cplusplus */

/* Signal that all the definitions are present. */
#define __bool_true_false_are_defined 1

#endif /* stdbool.h */

真假大小写

相应的真假大小写区别—— false/true 是标准 C++ 语言里新增的关键字,而 FALSE/TRUE 是通过 #define,用途是解决程序在 C 与 C++ 中环境的差异,以下是 FALSE/TRUE 在 windef.h 的定义:

1
2
3
4
5
6
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif

也就是说 FALSE/TRUE 是 int 类型,而 false/true 是 bool 类型。所以两者不一样的,只不过我们在使用中没有这种感觉,因为 C++ 会帮你做隐式转换。