Respuestas:
La página en cppreference.com dice:
Después de toda expansión y evaluación macro de expresiones definidas y __has_include (desde C ++ 17), cualquier identificador que no sea un literal booleano se reemplaza con el número 0 (esto incluye identificadores que son palabras clave léxicamente, pero no tokens alternativos como y )
Entonces ambos fooy barson reemplazados por 0.
En una #ifdeclaración, cualquier identificador que permanezca después de la sustitución de macro (excepto para truey false) se reemplaza con la constante 0. Entonces su directiva se convierte
#if 0 == 0
cual es verdad.
Esto se debe a que fooni barse les ha dado ninguna definición o valor, por lo que son iguales (es decir, reemplazados por un valor "0"). Los compiladores darán advertencias sobre esto.
El MSVCcompilador (Visual Studio 2019) ofrece lo siguiente:
advertencia C4668: 'foo' no se define como una macro de preprocesador, reemplazando con '0' para '# if / # elif'
advertencia C4668: 'bar' no se define como una macro de preprocesador, reemplazando con '0' para '#if / # elif '
Por VALUElo tanto, se le da el valor '0' (predeterminado para foo) y bartambién tiene '0', por lo que se VALUE == barevalúa como "VERDADERO".
Del mismo modo, clang-clda lo siguiente:
advertencia: 'foo' no está definido, se evalúa a 0 [-Wundef]
advertencia: 'barra' no está definido, se evalúa a 0 [-Wundef]
MSVCy clang-cl, esta advertencia se puede deshabilitar (ya sea específicamente o estableciendo un 'nivel' de advertencia apropiado).
Para lograr lo que busca, intente esto:
#include <iostream>
#define DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
En este caso, puede desactivar las declaraciones de depuración cambiando "define" a "undef".
#include <iostream>
#undef DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
Es posible que su compilador le permita definir DEPURACIÓN fuera del código, en cuyo punto puede reducir el código a
#include <iostream>
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
Y luego invoque el compilador con una opción como -DDEBUG = 0
Consulte el capítulo sobre Programación defensiva en Steve McConnell, "Código completo".