回答:
cppreference.comのページには、次のように記載されています。
すべてのマクロ展開と、定義された式および__has_include(C ++ 17以降)式の評価の後、ブールリテラルではない識別子は数値0に置き換えられます(これには、字句的にキーワードである識別子が含まれますが、およびのような代替トークンは含まれません)。
両方そうfoo
とbar
0に置き換えられます。
#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」をチェックしてください。