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 )
としても良いだろう。
ウェブマスター。本ブログでITを中心にいろいろな情報や意見などを提供しています。主にスマートフォン向けアプリやウェブアプリの開発を携わっています。ご用の方はコメントかコンタクトフォームにて。