0Pricing
C Academy · レッスン

条件付きコンパイル

ifdef とマクロです。

「条件付きコンパイル」はCoddyKit上の無料C Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C Academyコースには全4レッスンが含まれています。

プリプロセッサ

コンパイラーがコードを見る前に、プリプロセッサが実行されます。プリプロセッサは#で始まるすべての行、つまりインクルード、マクロ、条件分岐を処理します。

条件付きコンパイルを使うと、この段階で評価される条件に基づいてコードブロックを含めたり除外したりでき、1つのソースから異なるビルドを作成できます。

マクロを定義する

#defineでマクロを作成します。値を指定しなければ、後でテストできるフラグになります。

オブジェクト形式マクロは名前をテキストに置き換えます。一方、フラグは何かが設定されていることを示すだけです。

#define MAX_USERS 100   /* value macro */
#define DEBUG          /* flag macro */

ifdefとifndef

#ifdef NAMEは、NAMEが定義されている場合だけブロックを残します。#ifndefは、NAMEが定義されていない場合だけブロックを残します。

ここでは、デバッグ用の出力はデバッグビルドにだけ存在します。DEBUGが定義されていなければ、コンパイラーはその行を目にすることさえありません。

#include <stdio.h>
#define DEBUG

int main(void) {
#ifdef DEBUG
    printf("debug: starting\n");
#endif
    printf("running\n");
    return 0;
}

if、elif、else

#ifは、定数整数式を評価します。#elifや#elseと組み合わせると、複数の候補から選択できます。

ここでは、バージョン番号のマクロに基づいてコードを選択します。

#include <stdio.h>
#define VERSION 2

int main(void) {
#if VERSION >= 2
    printf("new feature on\n");
#else
    printf("legacy mode\n");
#endif
    return 0;
}

defined演算子

#ifの中では、defined(NAME)で定義の有無をテストし、&&や||で複数のテストを組み合わせられます。

1つの名前しかテストできない#ifdefよりも柔軟です。

#if defined(LINUX) && !defined(EMBEDDED)
    /* desktop Linux code */
#endif

コンパイル時に定義する

マクロをソースコードに直接書く必要はありません。-Dフラグを使えば、コマンドラインで定義できます。

これにより、ソースを編集せずにビルドシステムで機能を切り替えられます。-DDEBUGは、すべてのファイルの先頭に#define DEBUGを書くのと同じです。

gcc -DDEBUG -DVERSION=3 -o app app.c

プラットフォームの検出

コンパイラーは、対象プラットフォームを表すマクロをあらかじめ定義しています。これらを使って移植性の高いコードを書けます。

  • _WIN32 — Windows(32ビットまたは64ビット)
  • __linux__ — Linux
  • __APPLE__ — macOS/iOS

これらに基づいて分岐し、プラットフォームに適したAPIを呼び出します。

#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif

ヘッダーのインクルードガード

条件分岐の典型的な用途がインクルードガードです。これにより、ヘッダーが2回処理されるのを防ぎます。

最初のインクルードでガード用マクロを定義し、以降のインクルードではマクロがすでに定義されているため本体を読み飛ばします。

#ifndef UTILS_H
#define UTILS_H

int add(int a, int b);

#endif /* UTILS_H */

コードをコメントアウトする

#if 0 ... #endifを使うと、すでにコメントを含んでいるブロックでも確実に無効化できます。

/* */とは異なり安全に入れ子にできるため、デバッグ中にコードを一時的に除外する標準的な方法です。

#if 0
    legacy_function();   /* disabled for now */
    /* with internal comments too */
#endif

プリプロセッサ出力を確認する

コンパイラーが実際にコンパイルする内容を確認するには、-Eを指定してプリプロセッサだけを実行します。

すべてのインクルード、マクロ、条件分岐が展開されるため、マクロが期待どおりに動作しない場合に非常に役立ちます。

gcc -E app.c | less

実践的な機能切り替え

よく使われるパターンは、プロジェクト全体の機能を有効または無効にする単一の設定ヘッダーです。

1つの#defineを切り替えるだけで、すべてのファイルにあるガード付きブロックが反応します。これにより、オプション機能をコアコードから明確に分離できます。

#include <stdio.h>
#define FEATURE_LOGGING 1

int main(void) {
#if FEATURE_LOGGING
    printf("logging enabled\n");
#endif
    printf("app ready\n");
    return 0;
}

クイックチェック

コマンドラインでのdefineがどのように動作するか予測してください。

まとめ

これで、条件付きコンパイルを自在に制御できるようになりました。

  • #ifdef/#ifndefでマクロが定義されているかどうかをテストします
  • #if/#elif/#elseで定数式を評価し、defined()も使用できます
  • -DNAMEでコマンドラインからマクロを定義し、機能を切り替えます
  • あらかじめ定義されたプラットフォームマクロで移植性の高いコードを書き、インクルードガードで二重インクルードを防ぎます

次は、複数ファイルにまたがるコードの整理です。

よくある質問

「条件付きコンパイル」レッスンは無料ですか?

はい。「条件付きコンパイル」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C Academyコースには全4レッスンが含まれています。

「条件付きコンパイル」で何を学びますか?

ifdef とマクロです。 ブラウザで直接実行するハンズオンコードでC Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「条件付きコンパイル」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC Academyレッスンでコードを書いて実行できますか?

はい。すべてのC Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 条件付きコンパイル
  2. 複数ファイルのプロジェクト
  3. Makefile
  4. 静的ライブラリと共有ライブラリ
← C Academyに戻る