【C/C++】#if 0を使ったコメントアウトの話【西田の戯言。】

プログラミングにおいて、コードの可読性に欠かせないコメントアウト。今回はC言語のコメントアウトに関する話です。初歩的な話ですがお付き合い下さい。

コメントアウト

コメントアウトは、プログラミングにおいて欠かせないものです。それだけで可動性を高めることもできます。コードの説明で主に使われます。

コメントアウトの基本的な動作は、コンパイラに無視されるです。コンパイラがコンパイル時に解析するコードから無視されるので、最終的にバイナリには一切現れません。

C言語においての代表的なコメントアウトの種類は2つ。

まず一つが単行のコメントアウト//を使用する方法です。

int main() 
{
    // この部分がコメントアウトになる

    int a; // 「//」以降の分もコメントアウトになる
    return 0;
}

このコメントアウトでは、1行の中で//以降のコードが全てコメントアウトとなり、コンパイラに無視されます。

一方、複数行に渡るコメントアウトは/* */となります。

int main()
{
    /* 閉じるまで
        複数行が
        コメントアウトになりますよ
    */

    int a; /* 行の後ろにも仕込める */
    return 0;
}

こちらは、まとまったコメントに使用することもできますし、//のように行の後ろに仕込むことができます。ただし、最後は*/で閉じる必要がありますので、煩わしさでいうと1行で完結するなら//のほうがいいですね。

ちなみに、//によるコメントアウトが正式にC言語の仕様となったのはC99以降となりますので、古いコードや環境的に古い処理系が求められる、伝統的あるいは何らかの理由で古い処理系のコーディングルールを採用している場合、1行コメントでも/* */を求められることがあります。組み込みエンジニアとかは、/* */コメントを好む人が多い印象です。私もそうですし。

プリプロセッサによるコード無効化

さて、代表的なコメントアウト方法を2つご紹介しましたが、もう一つ、覚えておくと便利なものがあります。プリプロセッサを使ったコード無効化です。

プリプロセッサとは、コンパイラがコンパイルする前にその準備として処理される内容を記したものです。C言語におけるプリプロセッサとは、例えば#defineとは#ifdefとかです。C言語では必須の#includeもプリプロセッサの一種です。

コンパイラはプリプロセッサがあらかじめ処理しておいたコードをコンパイルします。例えば以下のようなコードがあったとしましょう。

#define TMP (100)

int main()
{
    int a = TMP;
    printf("%d\n", a);

    return 0;
}

(説明のため#includeを省略)

これは、プリプロセッサで以下のような形ひ変換され、コンパイラに渡されます。

int main()
{
   int a = 100;
    printf("%d\n", a);

    return 0;
}

そして、本題。プリプロセッサには#ifというディレクティブが存在しています。これは、プリプロセッサにおける条件文になります。

ifにあたるのが#ifelseにあたるのが#elseelse ifにあたるのが#elifです。#ifは最後#endifで閉じられている必要があります。

で、#ifは通常の条件式と同じように、条件式を0あるいは、falseになるようにすると、その中のコードは実行されません。

#if 0
printf("Code you don't want to execute\n");
#endif

こうすることで、#if 0#endifの中のコードは、コンパイルされません。コメントアウトと同じように、バイナリにはこの部分が一切現れません。

出来上がりの効能としては/* */のコメントアウトと同じですが、このコメントアウトには一つメリットがあります。それが「簡単にコードを有効化させることができる」ということです。

C言語のif文は0以外の値が条件式に含まれるとtrueとなります。よって、#if 0#if 1みたいにしてあげると、それだけでコメントアウトが無効化され、コンパイルの対象になります。

使い道としては、コードの有効化・無効化を切り替えることがあるコード、呼び出し部分を開発済みだが実装そのものは未実装という場合などが考えられます。それ以外だと、コードを含んでおきたいが、コメントアウトによるコメントとは区別しておきたいなんてときにも有効ですね。

ちなみに、多くのエディタのシンタックスハイライトでは、プリプロセッサによって無効化されるコードはコメントアウトと同じように色付けされるか、実行されないと分かる形で色分けされます。

VSCodeでの#if 0によるシンタックスハイライト

コメントアウトでコードを消す

コメントアウトは基本的に、コードの説明を記述するという用途で使用されますが、使用しないコードを消さずにコメントアウトするという使われ方をすることがあります。

これは、開発途中のデバッグ等で不具合を特定したり、あるいはコード置き換え等でよく起きますが、可読性の面からはあまり好まれません。動かないコードは消すべきだからです。

ただ、どうしてもコードを将来のために残しておきたいということはあると思います。それを考慮すると、#if 0で残しておいてあげると、まだマシなのかなぁ・・・。とか思いますね。

ほなまた。


この記事を書いた人

西田(総合情報学部 情報学科 2021年入学)

通信研究会OB。当ホームページの保守運用を支援しています。組み込み系のソフトウェアエンジニア。応用情報技術者・修習技術者。