Respostas:
A página em cppreference.com indica:
Após toda expansão e avaliação de macro de expressões definidas e __has_include (desde C ++ 17), qualquer identificador que não seja um literal booleano é substituído pelo número 0 (isso inclui identificadores que são palavras-chave lexicamente, mas não tokens alternativos como e )
Então, ambos fooe barsão substituídos por 0.
Em uma #ifdeclaração, qualquer identificador que permanece após a substituição da macro (exceto truee false) é substituído pela constante 0. Então sua diretiva se torna
#if 0 == 0
que é verdade.
Isso ocorre porque nem foonem barter sido dada qualquer definição ou valor - então eles são os mesmos (ou seja substituído por um valor "0"). Os compiladores darão avisos sobre isso.
O MSVCcompilador (Visual Studio 2019) fornece o seguinte:
aviso C4668: 'foo' não está definido como uma macro de pré-processador, substituindo por '0' para '# if / # elif'
aviso C4668: 'bar' não está definido como uma macro de pré-processador, substituindo por '0' para '#if / # elif '
Assim, VALUEé dado o valor '0' (padrão para foo) e bartambém possui '0', então VALUE == baravalia como "TRUE".
Da mesma forma, clang-clfornece o seguinte:
aviso: 'foo' não está definido, avalia como 0 [-Wundef]
aviso: 'bar' não está definido, avalia como 0 [-Wundef]
MSVCe clang-cl, esse aviso pode ser desabilitado (especificamente, ou definindo um nível de aviso apropriado).
Para realizar o que você procura, tente o seguinte:
#include <iostream>
#define DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
Nesse caso, você pode desativar as instruções de depuração alterando o "define" para "undef".
#include <iostream>
#undef DEBUG
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
Você pode achar que seu compilador permite definir DEBUG fora do próprio código; nesse momento, você pode reduzir o código para
#include <iostream>
int main() {
#ifdef DEBUG
std::cout << "WORKS!" << std::endl;
#endif
}
E, em seguida, chame o compilador com uma opção como -DDEBUG = 0
Confira o capítulo sobre programação defensiva em Steve McConnell, "Código completo".