ifディレクティブマクロ比較


25

#if次のコードの条件が満たされるのはなぜですか。

#include <iostream>
#define VALUE foo    

int main() {    
#if VALUE == bar
    std::cout << "WORKS!" << std::endl;
#endif // VALUE
}

回答:


26

cppreference.comページには、次のように記載されています。

すべてのマクロ展開と、定義された式および__has_include(C ++ 17以降)式の評価の後、ブールリテラルではない識別子は数値0に置き換えられます(これには、字句的にキーワードである識別子が含まれますが、およびのような代替トークンは含まれません)。

両方そうfoobar0に置き換えられます。


C ++ 98、C ++ 03、C ++ 11、C ++ 14はどうですか?
ケララカ

1
@kelalakaすべて同じです。C89以来ずっとそうでした。
SSアン

1
@kelalaka「C ++ 17以降」は「and __has_include」の部分のみを指します。C ++ 17より前は同じで、その部分が省略されていました。
BessieTheCow

15

#ifステートメント、マクロ置換後に残る任意の識別子は、(を除くtruefalse)定数に置き換えられます0。だからあなたの指令は

#if 0 == 0

それは本当です。


明確にするため、「の#define VALUE fooが」シンボル名「FOO」と同じ値に解決するために、記号「VALUE」を定義し、それは0として解釈されるようにシンボル「FOO」は、意味を持たない
ManicDee

14

どちらからですfooでもbarそれらが同じであるので(すなわち「0」の値に置き換えられていない) -任意の定義や価値を与えられているが。コンパイラはこれについて警告を出します。

MSVCコンパイラ(Visual Studioの2019)は、以下を与えます:

警告C4668: 'foo'はプリプロセッサマクロ
として定義されておらず、 '#if /#elif'の代わりに '0'に置き換えられています警告C4668: 'bar'はプリプロセッサマクロとして定義されておらず、 '#ifの代わりに' 0 'に置き換えられています/#elif '

そのVALUEため、値「0」(のデフォルトfoo)が与えられ、「0」barもあるためVALUE == bar、「TRUE」と評価されます。

同様にclang-cl、次のようになります。

警告: 'foo'は定義されていない、0に評価される[-Wundef]
警告: 'bar'は定義されていない、0に評価される[-Wundef]


警告は必須ですか、それともコンパイラの機能ですか?
ケララカ

1
@kelalaka私の知る限り、コンパイラの「警告」は必須ではありません。MSVCおよびclang-clコンパイラを使用しても、この警告は無効にできます(具体的に、または適切な警告「レベル」を設定することにより)。
Adrian Mole

0

あなたが何をしているのかを達成するには、これを試してください:

#include <iostream>
#define DEBUG  

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

この場合、「define」を「undef」に変更することで、デバッグステートメントをオフにできます。

#include <iostream>
#undef DEBUG  

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

コンパイラでは、コード自体の外部でDEBUGを定義できるため、コードを次のように削減できます。

#include <iostream>

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

次に、-DDEBUG = 0などのオプションを指定してコンパイラを起動します。

Steve McConnellのDefensive Programmingの章「Code Complete」をチェックしてください。

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