天天看點

【原創】bool、BOOL 和 _Bool 辨析

      最近在搞跨平台編譯的時候又遇到了 c99 标準支援的問題,主要展現在布爾類型問題上面。于是乎決定把這個問題徹底搞搞清楚,遂成此文。 

【 bool、bool 和 _bool 的差別 】 

      bool 類型在 c++ 中以關鍵字的形式被支援,表示布爾類型,其對應變量的值隻有真(true)和假(false)兩種值。 

      bool 類型在頭檔案 <windef.h> 中定義為 typedef int bool;在頭檔案 <wtypes.h> 中定義為 typedef long bool;

      bool 類型的長度視實際環境來定,一般可認為是 4 個位元組。 

      bool 是微軟定義的表達布爾邏輯的類型。與 c++ 中的 bool 類型不同是,它是一個三值邏輯:true、false 和 error。當傳回值為大于 0 的整數時為 true,傳回值為 0 時為 false,傳回值為 -1 時為 error。 

      _bool 是 c99 标準中定義的一個新關鍵字,以提供布爾類型。c2008 草案中隻規定了 _bool 類型的大小至少應能夠存放 0 和 1 這兩個值。而并沒有規定具體的大小。這交給編譯器自由發揮了。 

【跨平台如何使用布爾類型】 

      c++ 裡有專門的 bool 關鍵字。但是在 c99 之前,c 語言裡沒有這樣的類型。從 c99 标準開始,增加了關鍵字 _bool 用來表示布爾類型。是以隻要你的編譯器支援 c99,你就可以直接使用布爾型了(當然,vc,vs系列編譯器均不支援 c99)。除此之外,c99 為了在 c 中相容 c++ 裡對布爾類型的定義,又增加了一個頭檔案 stdbool.h。并在其中定義了 bool、true 和 false,讓我們可以像 c++ 一樣的定義和使用布爾類型。 

使用布爾類型的幾種方式: 

a. 自己定義的“仿布爾類型” 

在 c99 标準被支援之前,我們常常自己模仿定義布爾類型,方式有很多種,常見的有下面兩種:

/* 第一種方法 */ 

<a href="http://my.oschina.net/moooofly/blog/180380#">?</a>

1

2

3

<code>typedef</code> <code>int</code> <code>bool</code><code>;</code>

<code>#define true 1</code>

<code>#define false 0</code>

/* 第二種方法 */ 

<code>enum</code> <code>bool</code><code>{</code><code>false</code><code>,</code><code>true</code><code>};</code>

b. 使用 c99 新增的關鍵字 _bool

      c99 新增關鍵字 _bool 類型的長度為 1,隻能取值為 0 或 1 。将任意非零值指派給 _bool 類型變量,都會先轉換為 1,表示為真。将零值指派給 _bool 類型,結果為 0,表示為假。 

c. 使用 c99 新增頭檔案 stdbool.h 

      在 c++ 中,通過 bool 來定義布爾變量,通過 true 和 false 對布爾變量進行指派。c99 為了讓我們能夠寫出與 c++ 相容的代碼,添加了頭檔案 &lt;stdbool.h&gt; 。是以我們隻要包含了該頭檔案,就可以像 c++ 中使用布爾變量的方式進行操作。 

在我自己的 linux 系統中查找 stdbool.h 頭檔案,找到兩處: 

1. 系統定義 

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

<code>[root@betty ~]# vi /usr/lib/syslinux/com32/include/stdbool.h</code>

<code>/*</code>

<code> </code><code>* $id: stdbool.h,v 1.1 2003/04/16 06:32:31 hpa exp $</code>

<code> </code><code>*</code>

<code> </code><code>* stdbool.h</code>

<code> </code><code>*/</code>

<code>#ifndef _stdbool_h</code>

<code>#define _stdbool_h</code>

<code>#ifndef __cplusplus</code>

<code>#if !defined(__stdc_version__) || (__stdc_version__ &lt; 199901l)</code>

<code># if !defined(__gnuc__) ||(__gnuc__ &lt; 3)</code>

<code>  </code><code>typedef</code> <code>char</code> <code>_bool;          </code><code>/* for c compilers without _bool */</code>

<code># endif</code>

<code>#endif</code>

<code>#define bool  _bool</code>

<code>#define true  1</code>

<code>#else</code>

<code>/* c++ */</code>

<code>#define bool  bool</code>

<code>#define true  true</code>

<code>#define false false</code>

<code>#define __bool_true_false_are_defined 1</code>

<code>#endif /* _stdbool_h */</code>

2. gcc 定義

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

<code>[root@betty ~]# vi /usr/lib/gcc/x86_64-redhat-linux/4.1.1/include/stdbool.h</code>

<code>/* copyright (c) 1998, 1999, 2000 free software foundation, inc.</code>

<code>this file is part of gcc.</code>

<code>gcc is free software; you can redistribute it and/or modify</code>

<code>it under the terms of the gnu general public license as published by</code>

<code>the free software foundation; either version 2, or (at your option)</code>

<code>any later version.</code>

<code>gcc is distributed in the hope that it will be useful,</code>

<code>but without any warranty; without even the implied warranty of</code>

<code>merchantability or fitness for a particular purpose.  see the</code>

<code>gnu general public license for more details.</code>

<code>you should have received a copy of the gnu general public license</code>

<code>along with gcc; see the file copying.  if not, write to</code>

<code>the free software foundation, 51 franklin street, fifth floor,</code>

<code>boston, ma 02110-1301, usa.  */</code>

<code>/* as a special exception, if you include this header file into source</code>

<code>   </code><code>files compiled by gcc, this header file does not by itself cause</code>

<code>   </code><code>the resulting executable to be covered by the gnu general public</code>

<code>   </code><code>license.  this exception does not however invalidate any other</code>

<code>   </code><code>reasons why the executable file might be covered by the gnu general</code>

<code>   </code><code>public license.  */</code>

<code> </code><code>* iso c standard:  7.16  boolean type and values  &lt;stdbool.h&gt;</code>

<code>#define bool    _bool</code>

<code>#define true    1</code>

<code>#define false   0</code>

<code>#else /* __cplusplus */</code>

<code>/* supporting &lt;stdbool.h&gt; in c++ is a gcc extension.  */</code>

<code>#define _bool   bool</code>

<code>#define bool    bool</code>

<code>#define false   false</code>

<code>#define true    true</code>

<code>#endif /* __cplusplus */</code>

<code>/* signal that all the definitions are present.  */</code>

<code>#define __bool_true_false_are_defined   1</code>

<code>#endif  /* stdbool.h */</code>

其實這兩個頭檔案的定義本身還隐形的說明了一些資訊,閱者自斟。

繼續閱讀