C言語にだってbool型はある
-誤解と避けるべき落とし穴-

■この記事の概要

この記事では、C言語のbool型を正しく使うためのポイントを解説しています。

特に、++--の誤用による予期しない挙動や、不適切な使い方を取り上げています。


ブール型 _Bool の使用例

int main(void){
    _Bool x = 1 ;
    _Bool y = 0 ;
}

C99で新しく導入されたブール型は
_Boolです。
アンダーバーから始まる変な名前になったのは既に作られた古い自作のブール型との競合を避けるためです。
古い自作のブール型の例:
typedef enum {false, true} bool ;

boolと書くとエラーになる例

int main(void){
    bool x = true ;
    bool y = false ;
}

C99準拠のコンパイラでも、単にboolと書くと、コンパイルエラーになってしまいます。

stdbool.hを追加するとエラーにならない

#include <stdbool.h>//★追加する
int main(void){
    bool x = true ;
    bool y = false ;
}

stdbool.hを追加するとエラーになりません。

bool型のサイズは処理系依存

#include <stdbool.h>
#include <stdio.h>
int main(void){
    printf("bool型のサイズ=%zu\n",
        sizeof(bool)
    ) ;
}

sizeof(bool)の結果は処理系依存です。
gcc/clangでは結果は1になりました。

bool型に0/1以外を代入してもエラーにならない

#include <stdbool.h>
#include <stdio.h>
int main(void){
    //bool型は非ゼロは皆1になる
    bool x = 0x100;
    printf("%x\n",x) ;
}

0/1しか取れない bool 型変数に
0x100を代入するとエラーになりそうですが
エラーにも警告にもなりません。
非ゼロの値はすべて1になります。

■bool型を++/--してはいけない

warning: increment of a boolean expression

警告:真偽値(0/1)しか取れないbool型を加算した
[-Wbool-operation]

#include <stdbool.h>
#include <stdio.h>
int main(void){
    bool x = 0;  
    //1+1=1
    x++ ;   printf("x++ = %d\n",x);
    x++ ;   printf("x++ = %d\n",x);
    x++ ;   printf("x++ = %d\n",x);
    x++ ;   printf("x++ = %d\n",x);
    
    //toggle
    x-- ;   printf("x-- = %d\n",x);
    x-- ;   printf("x-- = %d\n",x);
    x-- ;   printf("x-- = %d\n",x);
    x-- ;   printf("x-- = %d\n",x);
}

0/1しか取れない bool 型変数を
++/--するのは多分誤りと思われます。
C言語ではコンパイル出来てしまいますが
C++ではコンパイルエラーとなります。

➡gcc/clangの結果

./a.out
x++ = 1
x++ = 1
x++ = 1
x++ = 1
x-- = 0
x-- = 1
x-- = 0
x-- = 1

先のプログラムをgccでコンパイルして動かすと上記になります。
++とーーで動きが違うので注意して下さい。


参考:

非推奨だった bool 型に対するインクリメント演算子を削除

https://cpprefjp.github.io/lang/cpp17/remove_deprecated_increment_of_bool.html