回答:
cppreference.comのページには、次のように記載されています。
すべてのマクロ展開と、定義された式および__has_include(C ++ 17以降)式の評価の後、ブールリテラルではない識別子は数値0に置き換えられます(これには、字句的にキーワードである識別子が含まれますが、およびのような代替トークンは含まれません)。
両方そうfooとbar0に置き換えられます。
#ifステートメント、マクロ置換後に残る任意の識別子は、(を除くtrueとfalse)定数に置き換えられます0。だからあなたの指令は
#if 0 == 0
それは本当です。
どちらからです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]
MSVCおよびclang-clコンパイラを使用しても、この警告は無効にできます(具体的に、または適切な警告「レベル」を設定することにより)。
あなたが何をしているのかを達成するには、これを試してください:
#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」をチェックしてください。