Em C e em alguns idiomas semelhantes, comparar expressões booleanas para igualdade com false
ou true
é um hábito perigoso.
Em C, qualquer expressão escalar (numérica ou ponteiro) pode ser usada em um contexto booleano, por exemplo, como a condição de uma instrução if
. A regra C é que if (cond)
é equivalente a if (cond != 0)
- ou seja, zero é falso e qualquer valor diferente de zero é verdadeiro. Se cond
for do tipo de ponteiro, 0
será tratado como uma constante de ponteiro nulo; if (ptr)
significa if (ptr != NULL)
.
Isso significa que
if (cond)
e
if (cond == true)
não significa a mesma coisa . O primeiro é verdadeiro se cond
for diferente de zero; o segundo é verdadeiro apenas se for igual a true
, que em C (se você tiver #include <stdbool.h>
) é simplesmente 1
.
Por exemplo, a função isdigit()
declarada em <ctype.h>
retorna um valor int
, 0
se o argumento for um dígito, diferente de zero se não for. Pode retornar 42
para indicar que a condição é verdadeira. A comparação de 42 == true
falhará.
Acontece que 0
é o único valor considerado falso, portanto, a comparação de igualdade para false
funcionará; if (!cond)
e if (cond == false)
fazem a mesma coisa. Mas se você vai tirar proveito disso, você tem que lembrar que comparando com false
está ok, e comparando com true
não está. Pior ainda, comparar com true
funcionará na maior parte do tempo (por exemplo, os operadores de igualdade e relacional sempre geram 0
ou 1
). Isso significa que quaisquer erros que você introduzir usando isso ainda podem ser difíceis de rastrear. (Não se preocupe, eles aparecerão assim que você demonstrar o código para um cliente importante.)
C ++ tem regras ligeiramente diferentes; por exemplo, seu tipo bool
é um pouco mais integrado ao idioma e if (cond)
converte cond
para tipo bool
. Mas o efeito é (principalmente) o mesmo.
Algumas outras linguagens têm o que se pode chamar de booleanos de melhor comportamento, de modo que cond == true
e cond == false
(ou seja qual for a sintaxe) é seguro. Mesmo assim, cada idioma que vi tem um operador not
ou !
; está lá, então você também pode usá-lo. Usar cond == false
em vez de !cond
ou not cond
, na minha opinião, não melhora a legibilidade. (É verdade que o caractere !
pode ser difícil de ver de relance; às vezes, adiciono um espaço após o !
para evitar isso.)
E muitas vezes você pode evitar o problema e melhorar a clareza reorganizando o código um pouco. Por exemplo, em vez de:
if (!cond) {
do_this();
}
else {
do_that();
}
você pode escrever:
if (cond) {
do_that();
}
else {
do_this();
}
Isso não é sempre melhor, mas não custa procurar oportunidades onde está.
Resumo: Em C e C ++, as comparações de igualdade com true
e false
são perigosas, excessivamente detalhadas e pobres. Em muitos outros idiomas, essas comparações podem não ser perigosas, mas ainda são excessivamente verbosas e pobres.