条件コンパイル
プリプロセッサはソースファイルの一部の条件コンパイルをサポートします。 この動作は #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言語リファレンス
|