ifdefのブール値:「#ifdefA && B」は、「#if defined(A)&& defined(B)」と同じですか?


83

C ++では、これは次のとおりです。

#ifdef A && B

と同じ:

#if defined(A) && defined(B)

そうではないと思っていたのですが、コンパイラー(VS2005)との違いを見つけることができませんでした。


1
:の可能性重複stackoverflow.com/questions/965700/...:私は、彼らはCとC ++ですが、プリプロセッサは基本的に同じであることがわかりstackoverflow.com/questions/5085533/...
チロSantilli郝海东冠状病六四事件法轮功

誰かが標準を引用して解釈し、それが合法かどうかを判断しますか(確実に機能するはずはありませんが、コンパイルする必要があります)?「16の前処理ディレクティブ」の章を15分読んだ後、読むことができません。
CiroSantilli郝海东冠事病六四事件法轮功2015

回答:


91

それらは同じではありません。最初のものは機能しません(私はgcc 4.4.1でテストしました)。エラーメッセージは次のとおりです。

test.cc:1:15:警告:#ifdefディレクティブの最後に追加のトークン

複数のものが定義されているかどうかを確認したい場合は、2番目のものを使用してください。


確認していただきありがとうございます。私はMicrosoftのコンパイラを使用していて、それを許可しているようですが、それは私には正しくないようでした。
クリデル2009

2
単一のコンパイラを使用して物事を証明することはできません。これが無効であると述べている規格を参照してください。
軌道上でのライトネスレース

@LightnessRacesinOrbitただし、一部のコンパイラは標準を拡張しています。「特定のコンパイラで動作する」と言っても、それが有効であることを証明する試みではありません。特定のコンパイラが特定の方法で標準を拡張していることに注意してください。
モニカの訴訟に資金を提供する2016年

@QPaysTaxes:同意しましたが、この回答はそれを行いません。これは、「C ++ ....で」始まる質問に、C ++に関する一般的な事実と思われるもので応答します。一見したところ、エヴァンは1つのコンパイラで理論をテストし、言語自体からの保証として、すべての人に当てはまると想定しました。この動作がGCC拡張であると判断し、「これはGCC拡張です」(参照資料へのリンク付き)と言った場合、それは問題ありません。(この特定の質問に対する実際の回答ではありませんが)
軌道でのライトネスレース2016年

1
いくつかの陽性テストがそれ有効であることを「証明」することできませんが、それ有効でないこと、または少なくとも使用することが推奨されないことを証明するには、単一の陰性で十分です。標準を参照するのは良いことですが、少なくとも1つの主要なコンパイラで機能しないことを証明することは、この説明の目的で「機能しない」と言うのに十分な証拠です。
zeel 2018年

48

条件付きコンパイル

#ifディレクティブで定義された演算子を使用して、プリプロセッサ行内で0または1と評価される式を使用できます。これにより、ネストされた前処理ディレクティブを使用する必要がなくなります。識別子を囲む括弧はオプションです。例えば:

#if defined (MAX) && ! defined (MIN)  

定義された演算子を使用せずに、上記の例を実行するには、次の2つのディレクティブを含める必要があります。

#ifdef max 
#ifndef min

2
あなたの言うことは正しいですが、これは質問にまったく答えません、彼は2つが同じであるかどうか尋ねました...彼らはそうではありません。
Evan Teran

1
私はそれは、「彼らは同じではありません」と言うと思いますが、あなたはそれがCOND_A && COND_Bの#ifdefと異なっている(COND_A)&&定義された(COND_B)定義されたの#ifと同等のものを作る方法を説明していることがわかります
Svetlozarアンゲロフ

いずれにせよ、これは便利なメモです。
Paul Masri-Stone 2016

2

次の結果は同じです。

1.1。

#define A
#define B
#if(defined A && defined B)
printf("define test");
#endif

2.2。

#ifdef A
#ifdef B
printf("define test");
#endif
#endif

1
これが質問にどのように答えるかを説明するコメントを追加してください。あなたの答えからは明らかではありません。
ジェームズウッド

この回答は、技術的には正しいものの、質問に正確に回答するものではなく、誤った使用法を意味します。2つのブロックは同じことを行いますが、2つのifをネストすることは、&&を使用することと同じではありません。などの他の条件は#else、問題を引き起こす可能性があります。最初のオプションだけが、実際には質問者が求めたものを正確に意味します。
zeel 2018年

1

OPとは少し異なる例(UNIX / g ++)を探している人にとって、これは役立つかもしれません:

`

#if(defined A && defined B && defined C)
    const string foo = "xyz";
#else
#if(defined A && defined B)
    const string foo = "xy";
#else
#if(defined A && defined C)
    const string foo = "xz";
#else
#ifdef A
    const string foo = "x";
#endif
#endif
#endif
#endif

#else #ifの代わりに#elifを使用し、最後に10億の#endifを使用しないのはなぜですか...?
エリオット

-3

VS2015の時点では、上記のいずれも機能しません。正しいディレクティブは次のとおりです。

#if (MAX && !MIN)

詳細はこちら


2
C ++ではなくC#のドキュメントにリンクしています。
Revolver_Ocelot
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.