C言語の論理型は要注意

注意: この記事は1年以上前に掲載されたものです。情報が古い場合がありますのでお気を付け下さい。

C言語では論理値の扱い方に要注意である。C言語では厳密には論理型はなく、実際には整数値であたかも論理型を表現しているからである。

C言語で論理型の条件分岐をするときの注意点

C言語では以下のような論理型の書き方はしてはならない

if ( XXX == TRUE )

これは、C言語特有の問題で、コードによっては問題を引き起こす場合があるからである。というのは、C言語では論理値の比較は0かどうかで比較しているからである ((0であればfalse、それ以外であればtrue)) 。したがって、それを念頭に入れないと問題を引き起こすことがある。

問題を引き起こさない例

例えば、以下のコードは問題は顕在化しない。

#include <stdio.h>
#include <stdbool.h>

_Bool is_equal(int val1, int val2);

int main(void) {
    if (is_equal(1, 1) == true) {
        puts("equal");
    }else{
        puts("not equal");
    }
    return 0;
}

_Bool is_equal(int val1, int val2) {
    if (val1 == val2) {
        return true;
    } else {
        return false;
    }
}

上記の場合、is_equalという関数において、明確にfalseかtrueかを返しているため、問題とならない。

問題を引き起こす例

以下の場合は、問題を引き起こす。

#include <stdio.h>

int is_differ(int val1, int val2);

int main(void) {
    if (is_differ(1, 3) == true) {
        puts("differ");
    }else{
        puts("not differ");
    }
    return 0;
}

int is_differ(int val1, int val2) {
    return val1 - val2;
}

この場合、本来であれば「differ」が出力されることを期待するが、実際には「not differ」が出力されてしまう。これは、C言語に詳しい開発者の一部は「C言語の論理値の比較は0かそれ以外で行う」ことを知っているため、そのために「0か1である必要がない」と考えることがあるからである。

それを知らないと認識の問題が発生して、問題となる。

対策法

上記の場合はif (is_differ(1, 3) == true)をif (is_differ(1, 3))`にすれば良い。そうすれば、0以外はtrueとして扱われるため、想定通りの動作になる。

最後に

C言語の論理値の条件分岐は0かどうかで行われるので、それを知らないと思わぬ問題に遭遇してしまうことがある。

そのため、もし、if ( XXX == TRUE )というような書き方をしていたら、即座にif ( XXX )とするようにしよう。if ( XXX == FALSE )はFALSEが0ということは明らかなので問題ないが、整合性を考えるとif ( !XXX )としても良いだろう。

タイトルとURLをコピーしました