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 foo
et bar
sont remplacés par 0.
Dans une #if
instruction, tout identifiant qui reste après la substitution de macro (à l'exception de true
et 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 foo
ne leur bar
ont été attribuées - elles sont donc identiques (c'est-à-dire remplacées par une valeur "0"). Les compilateurs donneront des avertissements à ce sujet.
Le MSVC
compilateur (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, VALUE
la 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-cl
donne ce qui suit:
avertissement: 'foo' n'est pas défini, évalue à 0 [-Wundef]
avertissement: 'bar' n'est pas défini, évalue à 0 [-Wundef]
MSVC
et 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».