【C言語】
論理否定演算子!の落とし穴
if(!x==0){if(!x & y);}

warning: logical not is only applied to the left hand side of this comparison

警告:!の結合力は==よりも強い
[-Wlogical-not-parentheses]


この記事の概要

この記事は、C言語における論理否定演算子!の誤使用によるエラー例を解説しています。

特にif(!x == 0)のようなコードの誤解を避けるための適切な書き方や、演算子の結合順序による問題とその対策を示しています。


■if(!x == 0)は誤読しやすい

int f(int x){
    if(!x == 0) return  1;//良くない
    if((!x)==0) return  2;//あまり良くない
    if(!(x==0)) return  3;//あまり良くない
    return 0;
}

if(!x == 0)のコードの意図が
if((!x)==0)なのか
if(!(x==0))なのか、わかりません。


●if(!x == 0)の修正例

int f(int x) {
    if(x == 0)  return  4;//良い
    if(x != 0)  return  5;//良い
    return 0;
}

■if(!x & y)は誤読しやすい

warning: suggest parentheses around operand of ‘!’ or change ‘&’ to ‘&&’ or ‘!’ to ‘~’

警告:否定演算子!はビット演算子&より結合力が強い
[-Wparentheses]

int f(int x,int y) {
    if(!x & y)
        return  1;
    return  0;
}

原作者の意図が次のどれか保守者にはわかりません。

if(!x & y) 原作

if(!x && y){

if(~x & y){

if((!x) & y){

if((x==0) & y){

if((x & y) == 0){


■if(!strcpy(p1,p2))は多分バグ

int f(char *p1,char *p2){
    if(!strcpy(p1,p2))  
        return  1;
    return  0;
}

多分strcmpの間違い
strcpyは第一引数をオーム返しするだけなので
第一引数にNULLはあり得ない。


■if(!strcmp(p1,p2) == 0) は多分バグ

int f(char *p1,char *p2){
    if(!strcmp(p1,p2) == 0)  
        return  1;
    return  0;
}

多分否定演算子!が不要