条件コンパイル
プリプロセッサはソースファイルの一部の条件コンパイルをサポートします。 この動作は #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 は定数式です。
式は defined identifier または defined (identifier) 形式の単項演算子を含むことができます。 identifier がマクロ名として定義されているまたは identifier が __has_include である (C++17以上)場合、結果は 1 であり、そうでなければ結果は 0 です。
すべてのマクロ展開および defined および __has_include (C++17以上) 式の評価の後、ブーリアンリテラルでないあらゆる識別子は数値 0 で置き換えられます (これは字句的にキーワードである識別子も含まれますが、 and のような代替トークンは含まれません。
expression が非ゼロの値に評価される場合、制御対象のコードブロックは含まれ、そうでなければ、スキップされます。
|
ノート: |
(C++14未満) |
[編集] #ifdef, #ifndef
識別子が マクロ名として定義されている かどうか調べます。
#ifdef identifier は実質的に #if defined identifier と同等です。
#ifndef identifier は実質的に #if !defined identifier と同等です。
[編集] 例
#define ABCD 2 #include <iostream> int main() { #ifdef ABCD std::cout << "1: yes\n"; #else std::cout << "1: no\n"; #endif #ifndef ABCD std::cout << "2: no1\n"; #elif ABCD == 2 std::cout << "2: yes\n"; #else std::cout << "2: no2\n"; #endif #if !defined(DCBA) && (ABCD < 2*4-3) std::cout << "3: yes\n"; #endif }
出力:
1: yes 2: yes 3: yes
[編集] 欠陥報告
以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。
| DR | 適用先 | 発行時の動作 | 正しい動作 |
|---|---|---|---|
| CWG 1955 | C++14 | failed #elif's expression was required to be valid | failed elif is skipped |
[編集] 関連項目
| 条件コンパイル の C言語リファレンス
|