# 善用 `stdbool.h` 讓程式碼更快更簡潔 ## 故事的開始 筆者友人曾經跟我抱怨,他們的公司的程式碼使用 uint8_t 來定義布林值。並且判斷式的寫法,因為可讀性緣故會寫成如下: ```cpp if (true == b) { /* ... */ } ``` 當然可讀性好不好是見仁見智,但這樣的程式碼或許會有效能的隱憂的。 考量下面的兩個判斷式: ```cpp= #define true 1 uint8_t b; if (b) { ... } if (b == true) { ... } ``` 第一個判斷式只需判斷b是否為0,而第二個判斷則需要對1做比較。x86來說就是要把 test 指令換成 cmp; RISC-V 則是需要多一道指令來比較。 當然實際上跑起來是否變差倒也難說,像是 Andes 的 [N25](http://www.ovpworld.org/modeldocs/OVP_Model_Specific_Information_andes_riscv_N25.pdf) 有在 RISCV 做的延伸指令 beqc (branch if equal to a constant),所以上面兩個判斷其實在 N25 上效率是一樣的。 `beqc` 指令具體用法如下: ```cpp beqc $reg, 1, LABEL # if ($reg == 1), branch to LABEL ``` ## 不一樣的 _Bool 然而我卻在實驗中意外的發現,當我使用 stdbool.h 定義的 bool 的時候。是不會有我剛上述的變化的。 原因在於 stdbool.h 使用的 bool ,即為 _Bool 定義而成。根據 C99 [6.2.5](http://c0x.coding-guidelines.com/6.2.5.html) > An object declared as type `_Bool` is large enough to store the values 0 and 1. 因為 `_Bool` 只能為 0 或 1,所以編譯器可推斷 (`x == 1`) 等價於 (`x != 0`)。 ## 真的有差嗎? 我相信一定會有讀者好奇,如果我不寫 (b == true) 這樣子的程式碼,有沒有使用stdbool.h的定義有差嗎? 筆者這裡有個簡單的例子: ```cpp if (boolean_value == (VERSIOIN >= 22)) { ... } ``` VERSION 是個巨集定義產品的版本。這寫法的目的,期望達到同份程式碼只要控制編譯的選項,即達到產出不同版本的的程式碼。 當 VERSION 為 22 以上的時候,便會出現 (b == true) 的情境了。 除此之外,使用 stdbool.h 可以省下定義布林值的時間呢。