許多從 C++ 轉向 C 的開發者會驚訝發現:C89/C90 標準並無原生 bool 型別。本文釐清歷史脈絡、C99 標準引入、主流編譯器支援現況,並提供生產級相容方案。
bool、true、falseint(0 假、非 0 真)<stdbool.h>,定義 _Bool 關鍵字與 bool、true、false 巨集| 編譯器 | 版本 | C99 支援 | <stdbool.h> | 備註 |
|---|---|---|---|---|
| GCC | ≥ 3.0 | 完整 | ✅ | 需 -std=c99 或 -std=gnu99 |
| Clang | 所有 | 完整 | ✅ | 預設 C11 |
| MSVC | ≤ VS2010 | 無 | ❌ | 僅支援 C89 |
| MSVC | VS2012+ | 部分 | ✅ | VS2013 起支援 stdbool.h |
| VC6.0 | 1998 | 無 | ❌ | 經典老牌,教學常用但已淘汰 |
| Intel ICC | ≥ 10 | 完整 | ✅ |
// test_bool.c
#include <stdio.h>
#include <stdbool.h> // C99
int main() {
bool flag = true;
printf("bool size: %zu\n", sizeof(bool)); // 通常為 1 byte
printf("true: %d, false: %d\n", true, false);
return 0;
}
bool size: 1cannot open include file: 'stdbool.h'在專案通用標頭檔 compat.h 中定義:
#ifndef COMPAT_H
#define COMPAT_H
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
// C99 或更新標準
#include <stdbool.h>
#elif defined(__cplusplus)
// C++ 編譯器
// bool, true, false 為關鍵字
#else
// C89 或無 stdbool.h 的編譯器
typedef unsigned char bool;
#define true 1
#define false 0
#endif
#endif // COMPAT_H
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 直接用 int | 零依賴,極簡 | 語意不清,易混淆整數邏輯 | 極小型專案、教學代碼 |
| 自訂 typedef + 巨集 | 全平台通用,語意明確 | 需維護相容標頭檔 | 跨平台專案、支援舊編譯器 |
| 強制 C99 + stdbool.h | 標準化,現代化 | 捨棄不支援 C99 的舊工具鏈 | 新專案、現代編譯器環境 |
<stdbool.h>compat.h 方案bool 巨集汙染命名空間,統一由專案配置標頭提供true/false 而非 1/0,提升可讀性C 語言的 bool 之路反映了標準演進與工具鏈現實的博弈。理解 _Bool、stdbool.h、編譯器支援矩陣,並建立專案級相容層,是寫出可移植、可維護 C 代碼的關鍵一步。