Risposte:
La pagina su cppreference.com afferma:
Dopo tutta l'espansione e la valutazione delle macro di espressioni definite e __has_include (dal C ++ 17), qualsiasi identificatore che non è un letterale booleano viene sostituito con il numero 0 (questo include identificatori che sono parole chiave lessicali, ma non token alternativi come e ).
Quindi entrambi fooe barvengono sostituiti con 0.
In una #ifdichiarazione, qualsiasi identificatore che rimane dopo la sostituzione della macro (ad eccezione ditrue e false) viene sostituito con la costante 0. Quindi la tua direttiva diventa
#if 0 == 0
che è vero.
Questo perché fooné a nessuno dei due barè stata data alcuna definizione o valore, quindi sono uguali (ovvero sostituiti con un valore "0"). I compilatori daranno avvertimenti a riguardo.
Il MSVC compilatore (Visual Studio 2019) fornisce quanto segue:
avviso C4668: 'pippo' non è definito come una macro del preprocessore, sostituendo con '0' per '# if / # elif'
avviso C4668: 'bar' non è definito come una macro del preprocessore, sostituendo con '0' per '#if / # elif'
Quindi VALUEviene dato il valore '0' (predefinito per foo) ebar ha anche '0', quindi VALUE == barrestituisce "VERO".
Allo stesso modo, clang-clfornisce quanto segue:
avvertimento: 'pippo' non è definito, restituisce 0 [-Wundef]
avvertimento: 'barra' non è definito, restituisce 0 [-Wundef]
MSVCe clang-cl, questo avviso può essere disabilitato (in modo specifico o impostando un "livello" di avviso appropriato).
Per realizzare ciò che cerchi, prova questo:
#include <iostream>
#define DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
In questo caso è possibile disattivare le istruzioni di debug modificando "define" in "undef".
#include <iostream>
#undef DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
Potresti scoprire che il tuo compilatore ti consente di definire DEBUG al di fuori del codice stesso, a quel punto puoi ridurre il codice
#include <iostream>
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
E quindi invoca il compilatore con un'opzione come -DDEBUG = 0
Guarda il capitolo sulla programmazione difensiva in Steve McConnell, "Codice completo".