Відповіді:
На сторінці 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]
попередження: 'bar' не визначено, оцінюється до 0 [-Wundef]
MSVC
та та clang-cl
це попередження можна відключити (конкретно, або встановивши відповідний "рівень" попередження).
Щоб виконати те, що ви хочете, спробуйте:
#include <iostream>
#define DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
У цьому випадку ви можете вимкнути оператори налагодження, змінивши "визначити" на "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
Ознайомтеся з розділом «Оборонне програмування» у Стіві МакКоннел «Код завершений».