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 foo
y bar
son reemplazados por 0.
En una #if
declaración, cualquier identificador que permanezca después de la sustitución de macro (excepto para true
y false
) se reemplaza con la constante 0
. Entonces su directiva se convierte
#if 0 == 0
cual es verdad.
Esto se debe a que foo
ni bar
se 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 MSVC
compilador (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 VALUE
lo tanto, se le da el valor '0' (predeterminado para foo
) y bar
también tiene '0', por lo que se VALUE == bar
evalúa como "VERDADERO".
Del mismo modo, clang-cl
da lo siguiente:
advertencia: 'foo' no está definido, se evalúa a 0 [-Wundef]
advertencia: 'barra' no está definido, se evalúa a 0 [-Wundef]
MSVC
y 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".