【C言語】
tautological警告の意味と解決方法
(恒真式・恒偽式の冗長判定)

warning: overlapping comparisons always evaluate to true

警告: 重複する比較は常に真と評価される
[-Wtautological-overlap-compare]


■この記事の概要

この記事では、C言語で発生するtautologicalに関連する警告の原因と対処方法を詳しく解説します。

特に「恒真式」と「恒偽式」に焦点を当て、それらがコードにどのように影響するかを説明します。

無意味な条件分岐を回避するための書き方や、実際のコード例を交えた具体的な改善策も紹介します。

警告を理解し、効率的なプログラムを実装するための情報が満載です。

■常に真

#include <stdio.h>
#include <stdbool.h>
char *f(bool x){
    if(x == 1 || x != 1){//恒真式
        return  "真";
    }else {
        return  "偽";
    }
}
int main(void){
    printf("%s\n",f(true));
    printf("%s\n",f(false));
}

warning: logical ‘or’ of collectively exhaustive tests is always true
[-Wlogical-op]


■常に偽

#include <stdio.h>
#include <stdbool.h>
char *f(bool x){
    if(x == 1 && x != 1){//恒偽式
        return  "真";
    }else {
        return  "偽";
    }
}
int main(void){
    printf("%s\n",f(true));
    printf("%s\n",f(false));
}

warning: logical ‘or’ of collectively exhaustive tests is always false
[-Wlogical-op]


■数直線上有り得ない

#include <stdio.h>
char *f(int x){ 
    if(x < -100 && 100 < x){
        return  "ここには来ない:数直線上有り得ない";
    }else{
        return  "偽";
    }
}
int main(void){
    for(int x = -127;x<128;x++){
        printf("%s\n",f(x));
    }
}

数直線の上で
-100より小さくかつ
+100より大きい領域はありません。
x ⇦ ー100  100⇒x
NG:if(x < -100  && 100 < x){
OK:if(x < -100  ||  100 < x){
OK:if(-100<=x  &&  x<=100 ){


■数直線上の全域

#include <stdio.h>
char *f(int x){ 
    if(-100 < x || x < 100){
        return  "真";//全部来る:数直線上の全域
    }else{
        return  "偽";
    }
}
int main(void){
    for(int x = -127;x<128;x++){
        printf("%s\n",f(x));
    }
}

数直線の上で
-100より大きいか
+100より小さい領域は全領域です。
-100⇒x x⇦100


■何故か警告が出ない

#include    <stdbool.h>
bool f(bool x)
{
    if(x == true && x == false) {//何故か警告が出ない
        return  true;
    }
    return  false;
}

残念ながらこの警告はgccでは検出されず
clangのみが検出します。
又なぜかstdbool.hで定義している  
true/false マクロを使用すると警告が出なくなってしまいます。