名前空間
変種
操作

条件コンパイル

提供: cppreference.com
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (C++20未満)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
 

プリプロセッサはソースファイルの一部の条件コンパイルをサポートします。 この動作は #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 が非ゼロの値に評価される場合、制御対象のコードブロックは含まれ、そうでなければ、スキップされます。

ノート: #if cond1 ... #elif cond2 ... は #if cond1 ... #else #if cond3 ... と異なります。 cond1 が真の場合、2つめの #if はスキップされ、 cond3 が well-formed である必要はありませんが、 #elif の cond2 は有効な式でなければなりません。

(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言語リファレンス