【C言語】
空文とは何か?
-コンパイラは空のif文をエラーにしない-

warning: suggest braces around empty body in an ‘if’ statement

警告:if文直後のセミコロンは多分余計です
[-Wempty-body]


■この記事の概要

この記事では、C言語でif文やfor文の後に余分なセミコロンが含まれる場合の問題を解説しています。これにより、意図しない空の文が実行され、プログラムの挙動が不正になる可能性があります。C言語の仕様ではエラーとして扱われないため、警告オプションや注意深いコードレビューの重要性を強調しています。


■一番小さいC言語の関数

void    f1(void)
{
}

何もしない関数でもコンパイルエラーになりません。

■空文だけでもエラーになりません

void    f2(void)
{
    ;//空文はコンパイルエラーにならない
}

■波括弧だけでもエラーになりません

void    f3(void)
{
    {   //波括弧のブロックはコンパイルエラーにならない
        ;
    }
}

■だからif 文直後のセミコロン;は。。。

int f4(int x)
{
    if(x);{
        return  1;  
    }
    return  0;
}

■コンパイルエラーになりません

int f5(int x)
{
    if(x)
        ;   //空文
    {   //波括弧のブロック
        return  1;  //必ず通過する 
    }
    return  0;  //ここには制御が来ない  
}

コンパイラは上記のように解釈して
コンパイルエラーを出しません。
if(x)は成立してもしなくても then 節が空文なので何もしません。

if(x)の判定結果と無関係に波括弧のブロック内の return 1 は必ず通過します。

プログラムとしては間違っていますが、文法的にはC言語規格に準拠していて問題がないのでコンパイルエラーになりません。

■セミコロンが多すぎる

int x,y;
int main(void)
{
    if(x);{     //NG: セミコロンが多すぎる
        ;
    }
    if(y){
        ;
    } else;{    //NG: セミコロンが多すぎる
        ;
    }
    do;while(1);{//NG: セミコロンが多すぎる
        ;
    } 
}

セミコロンが多すぎます。
if(x);は空のthen 節となり
コンパイルエラーにならないので
プログラマは気が付かない場合があります。

■for文直後もエラーにならない

int f6(int x)
{
    for(;x;)   ;   //空文
    {  
        x--;  
    }
    return  x;
}

似たような間違いに上記の for文直後のセミコロンがありますが、
これは gccでは -Wmisleading-indentation(-Wallに含まれている)で検出されます。

参考:

EXP15-C. if、for、while 文と同じ行にセミコロンを使用しない

https://www.jpcert.or.jp/sc-rules/c-exp15-c.html