Réponses:
La page sur cppreference.com déclare:
Après toute expansion de macro et évaluation d'expressions définies et __has_include (depuis C ++ 17), tout identifiant qui n'est pas un littéral booléen est remplacé par le nombre 0 (cela inclut les identifiants qui sont des mots-clés lexicaux, mais pas des jetons alternatifs comme et ).
Donc, les deux fooet barsont remplacés par 0.
Dans une #ifinstruction, tout identifiant qui reste après la substitution de macro (à l'exception de trueet false) est remplacé par la constante 0. Donc votre directive devient
#if 0 == 0
ce qui est vrai.
En effet, ni aucune définition ni valeur foone leur baront été attribuées - elles sont donc identiques (c'est-à-dire remplacées par une valeur "0"). Les compilateurs donneront des avertissements à ce sujet.
Le MSVCcompilateur (Visual Studio 2019) donne ce qui suit:
avertissement C4668: «foo» n'est pas défini comme une macro de préprocesseur, remplaçant par «0» pour «# if / # elif»
avertissement C4668: «bar» n'est pas défini comme une macro de préprocesseur, remplaçant par «0» pour «#if / # elif '
Ainsi, VALUEla valeur «0» est donnée (par défaut pour foo) et a barégalement «0», donc est VALUE == barévalué à «VRAI».
De même, clang-cldonne ce qui suit:
avertissement: 'foo' n'est pas défini, évalue à 0 [-Wundef]
avertissement: 'bar' n'est pas défini, évalue à 0 [-Wundef]
MSVCet clang-cl, cet avertissement peut être désactivé (soit spécifiquement, soit en définissant un «niveau» d'avertissement approprié).
Pour accomplir ce que vous recherchez, essayez ceci:
#include <iostream>
#define DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
Dans ce cas, vous pouvez désactiver les instructions de débogage en remplaçant "define" par "undef".
#include <iostream>
#undef DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
Vous pourriez trouver que votre compilateur vous permet de définir DEBUG en dehors du code lui-même, à quel point vous pouvez réduire le code à
#include <iostream>
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
Et puis appelez le compilateur avec une option telle que -DDEBUG = 0
Consultez le chapitre sur la programmation défensive dans Steve McConnell, «Code Complete».