Ответы:
Страница на 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' не определен как макрос препроцессора, заменив на '0' для '# if / # elif'
предупреждение C4668: 'bar' не определен как макрос препроцессора, заменив на '0' для '#if / # Элиф»
Так VALUE
дается значение «0» (по умолчанию для foo
), а bar
также имеет «0», такVALUE == bar
оценивается как «ИСТИНА».
Аналогично, clang-cl
дает следующее:
предупреждение: 'foo' не определено, оценивается в 0 [-Wundef]
предупреждение: 'бар' не определено, оценивается в 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
Прочтите главу «Защитное программирование» Стива Макконнелла «Код завершен».