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 foo
e bar
são substituídos por 0.
Em uma #if
declaração, qualquer identificador que permanece após a substituição da macro (exceto true
e false
) é substituído pela constante 0
. Então sua diretiva se torna
#if 0 == 0
que é verdade.
Isso ocorre porque nem foo
nem bar
ter 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 MSVC
compilador (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 bar
também possui '0', então VALUE == bar
avalia como "TRUE".
Da mesma forma, clang-cl
fornece o seguinte:
aviso: 'foo' não está definido, avalia como 0 [-Wundef]
aviso: 'bar' não está definido, avalia como 0 [-Wundef]
MSVC
e 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".