最近在搞跨平台編譯的時候又遇到了 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++ 相容的代碼,添加了頭檔案 <stdbool.h> 。是以我們隻要包含了該頭檔案,就可以像 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__ < 199901l)</code>
<code># if !defined(__gnuc__) ||(__gnuc__ < 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 <stdbool.h></code>
<code>#define bool _bool</code>
<code>#define true 1</code>
<code>#define false 0</code>
<code>#else /* __cplusplus */</code>
<code>/* supporting <stdbool.h> 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>
其實這兩個頭檔案的定義本身還隐形的說明了一些資訊,閱者自斟。