条件コンパイル
プリプロセッサはソースファイルの一部の条件コンパイルをサポートします。 この動作は #if、 #else、 #elif、 #ifdef、 #ifndef および #endif 指令で制御されます。
構文
#if expression
|
||
#ifdef identifier
|
||
#ifndef identifier
|
||
#elif expression
|
||
#else
|
||
#endif
|
||
説明
条件プリプロセッシングブロックは #if、 #ifdef または #ifndef 指令で始まり、オプションで任意個の #elif 指令を含み、オプションで多くとも1個の #else 指令を含み、 #endif 指令で終わります。 あらゆる内側の条件プリプロセッシングブロックは別々に処理されます。
#if、 #elif、 #else、 #ifdef および #ifndef 指令はそれぞれ、いかなる内側の条件プリプロセッシングブロックにも属していない最初の #elif、 #else、 #endif 指令までのコードブロックを制御します。
#if、 #ifdef および #ifndef 指令は指定された条件をテストし (後述)、それが真に評価された場合、制御対象のコードブロックをコンパイルします。 その場合、後続の #else および #elif 指令は無視されます。 そうでなければ (指定された条件が偽に評価された場合)、制御対象のコードブロックはスキップされ、後続の #else または #elif 指令 (もしあれば) が処理されます。 前者の場合は、その #else 指令の制御対象のコードブロックは無条件にコンパイルされます。 後者の場合は、その #elif 指令は #if 指令であったかのように動作します。 条件をチェックし、その結果を基に制御対象のコードブロックをコンパイルするかスキップし、後者の場合は後続の #elif および #else 指令を処理します。 条件プリプロセッシングブロックは #endif 指令によって終了します。
条件の評価
#if, #elif
expression は、定数および
#define 指令を用いて定義された識別子のみを使用する、定数式です。 リテラルでなく
#define 指令を用いて定義されていないあらゆる識別子は 0 に評価されます。
式は defined identifier または defined (identifier) 形式の単項演算子を含んでも構いません。 これは identifier が
#define 指令を用いて定義されていれば 1 を返し、そうでなければ 0 を返します。 expression が非ゼロの値に評価された場合は制御対象のコードブロックが含まれ、そうでなければスキップされます。 使用された識別子が定数でなければ、それは 0 に置き換えられます。
|
ノート: |
(C11未満) |
#ifdef, #ifndef
識別子が #define 指令を用いて定義されたかどうか調べます。
#ifdef identifier は実質的に #if defined identifier と同等です。
#ifndef identifier は実質的に #if !defined identifier と同等です。
例
#define ABCD 2
#include <stdio.h>
int main(void)
{
#ifdef ABCD
printf("1: yes\n");
#else
printf("1: no\n");
#endif
#ifndef ABCD
printf("2: no1\n");
#elif ABCD == 2
printf("2: yes\n");
#else
printf("2: no2\n");
#endif
#if !defined(DCBA) && (ABCD < 2*4-3)
printf("3: yes\n");
#endif
}
出力:
1: yes
2: yes
3: yes
参考文献
- C11 standard (ISO/IEC 9899:2011):
- 6.10.1 Conditional inclusion (p: 162-164)
- C99 standard (ISO/IEC 9899:1999):
- 6.10.1 Conditional inclusion (p: 147-149)
- C89/C90 standard (ISO/IEC 9899:1990):
- 3.8.1 Conditional inclusion
関連項目
条件コンパイル の C++リファレンス
|