#if、#elif、#else、および #endif ディレクティブ
ソース ファイルの一部のコンパイルを制御するプリプロセッサ ディレクティブ。
ifCondition ... を#ifします。 |
---|
[ elifCondition ...] を#elif |
[#else ...] |
#endif |
パラメーター
項目 | 説明 |
---|---|
ifCondition |
評価する主な条件。 このパラメーターが 0 以外の値に評価された場合、この#if ディレクティブと、#elif、#else、または #endif ディレクティブの次のインスタンスの間のすべてのテキストが翻訳単位に保持されます。それ以外の場合、後続のソース コードは保持されません。 条件では、定義されたプリプロセッサ演算子を使用して、特定のプリプロセッサ定数またはマクロが定義されているかどうかを判断できます。この使用法は、 #ifdef ディレクティブの使用と同じです。 ifCondition パラメーターの値の制限については、「解説」セクションを参照してください。 |
elifCondition [省略可能] |
評価するその他の条件。
ifCondition パラメーターと以前のすべての#elif ディレクティブが 0 に評価され、このパラメーターが 0 以外の値に評価された場合、この#elif ディレクティブと、#elif、#else、または #endif ディレクティブの次のインスタンスの間のすべてのテキストが翻訳単位に保持されます。それ以外の場合、後続のソース コードは保持されません。 条件では、定義されたプリプロセッサ演算子を使用して、特定のプリプロセッサ定数またはマクロが定義されているかどうかを判断できます。この使用法は、 #ifdef ディレクティブの使用と同じです。 elifCondition パラメーターの値の制限については、「解説」セクションを参照してください。 |
解説
ソース ファイルの各 #if ディレクティブは、末尾の #endif ディレクティブと対応している必要があります。 任意の数の #elif ディレクティブが、#if ディレクティブと #endif ディレクティブの間に出現する可能性がありますが、最大 1 つの #else ディレクティブが許可されます。 #else ディレクティブ (存在する場合) は、#endif の前の最後のディレクティブである必要があります。 インクルード ファイルに含まれる条件付きコンパイル ディレクティブは、同じ条件を満たす必要があります。
#If、#elif、#else、#endif の各ディレクティブは、他の #if ディレクティブの text 部分の中に入れ子にできます。 入れ子になった各 #else、#elif、#endif ディレクティブは、先行する直近の #if ディレクティブに属します。
条件が 0 以外の値と評価されない場合、プリプロセッサは、#else ディレクティブの後にテキスト ブロックを選択します。 #else句を省略し、0 以外の値と評価される条件がない場合、テキスト ブロックは選択されません。
ifCondition パラメーターと elifCondition パラメーターは、次の要件を多く満たしています。
- 条件付きコンパイル式は 符号付き長い 値として扱われ、これらの式は C++ の式と同じ規則を使用して評価されます。
- 式は、整数型である必要があり、整数定数、文字定数、defined 演算子のみ含めることができます。
- 式では、 sizeof 演算子または型キャスト演算子を使用できません。
- ターゲット環境は整数のすべての範囲を表現できるとは限りません。
- 変換は型 int を long と同じで、 unsigned int はunsigned long と同じを表します。
- トランスレーターは、ターゲット環境とは別のコード値のセットに文字定数を翻訳できます。 ターゲット環境のプロパティを調べるには、ターゲット環境向けにビルドされたアプリケーションで LIMITS.H からマクロの値を確認します。
- この式は、環境に関する照会を実行できないように、ターゲット コンピューターの実装の詳細から分離しておく必要があります。
例
このセクションには、条件付きコンパイル プリプロセッサ ディレクティブの使用方法を示す例が含まれています。
定義された演算子の使用
次の例は、定義された演算子の使用方法を示しています。 識別子 CREDIT が定義されている場合、 クレジット 関数の呼び出しがコンパイルされます。 識別子 DEBIT が定義されている場合、 デビット 関数の呼び出しがコンパイルされます。 どちらの識別子も定義されていない場合は、 printerror 関数の呼び出しがコンパイルされます。 "CREDIT" と "credit" は、ケースが異なるため、C および C++ では個別の識別子であることに注意してください。
#if defined(CREDIT)
credit();
#elif defined(DEBIT)
debit();
#else
printerror();
#endif
入れ子になった#if ディレクティブの使用
次の例は、ディレクティブ#if入れ子にする方法を示しています。 この例では、DLEVEL という名前のシンボリック定数が以前に定義されていることを前提としています。 #elif ディレクティブと #else ディレクティブは、DLEVEL の値に基づいて、4 つの選択肢のいずれかを行うために使用されます。 定数 STACK は、DLEVEL の定義に応じて 0、100、または 200 に設定されます。 DLEVEL が 5 より大きい場合、STACK は定義されません。
#if DLEVEL > 5
#define SIGNAL 1
#if STACKUSE == 1
#define STACK 200
#else
#define STACK 100
#endif
#else
#define SIGNAL 0
#if STACKUSE == 1
#define STACK 100
#else
#define STACK 50
#endif
#endif
#if DLEVEL == 0
#define STACK 0
#elif DLEVEL == 1
#define STACK 100
#elif DLEVEL > 5
display( debugptr );
#else
#define STACK 200
#endif
ヘッダー ファイルを含める場合に使用する
条件付きコンパイルの一般的な用途は、同じヘッダー ファイルの多重インクルードを防ぐことです。 C++ では、ヘッダー ファイルでクラスが定義されることが多く、条件付きコンパイルコンストラクトを使用して複数の定義を防ぐことができます。 次の例では、シンボリック定数EXAMPLE_Hが定義されているかどうかを判断します。 その場合、ファイルは既に含まれており、再処理する必要はありません。そうでない場合は、その EXAMPLE を示すために定数EXAMPLE_Hが定義されます。H は既に処理されています。
#if !defined( EXAMPLE_H )
#define EXAMPLE_H
class Example
{
...
};
#endif // !defined( EXAMPLE_H )