In C e in alcuni linguaggi simili, confrontare espressioni booleane per l'uguaglianza false
o true
è un'abitudine pericolosa.
In C qualsiasi espressione scalare (numerica o puntatore) può essere utilizzata in un contesto booleano, ad esempio come condizione di if
un'istruzione. La regola C if (cond)
è equivalente a if (cond != 0)
- cioè, zero è falso e qualsiasi valore diverso da zero è vero. Se cond
è di tipo puntatore, 0
viene trattato come una costante puntatore null; if (ptr)
significa if (ptr != NULL)
.
Ciò significa che
if (cond)
e
if (cond == true)
non significa la stessa cosa . Il primo è vero se cond
è diverso da zero; il secondo è vero solo se è uguale a true
, che in C (se hai #include <stdbool.h>
) è semplicemente 1
.
Ad esempio, la isdigit()
funzione dichiarata in <ctype.h>
restituisce un int
valore, 0
se l'argomento è una cifra, diverso da zero se non lo è. Può tornare 42
per indicare che la condizione è vera. Il confronto 42 == true
fallirà.
Succede che 0
è l'unico valore considerato falso, quindi il confronto per l'uguaglianza false
funzionerà; if (!cond)
e if (cond == false)
fare la stessa cosa. Ma se ne trarrai vantaggio, devi ricordare che il confronto con false
è ok e il confronto con true
non lo è. Peggio ancora, il confronto con true
funzionerà per la maggior parte del tempo (ad esempio, l'uguaglianza e gli operatori relazionali producono sempre 0
o 1
). Ciò significa che qualsiasi bug che introduci usando questo potrebbe essere difficile da rintracciare. (Non preoccuparti, verranno visualizzati non appena avrai demo del codice su un client importante.)
C ++ ha regole leggermente diverse; ad esempio, il suo bool
tipo è un po 'più strettamente integrato nel linguaggio e si if (cond)
converte cond
in tipo bool
. Ma l'effetto è (principalmente) lo stesso.
Alcune altre lingue hanno ciò che si potrebbe definire booleani meglio educati, in modo tale che cond == true
e cond == false
(o qualunque sia la sintassi) è sicuro. Anche così, ogni lingua che ho visto ha un operatore not
o !
; è lì, quindi potresti anche usarlo. L'utilizzo cond == false
piuttosto che !cond
o not cond
non migliora, secondo me, la leggibilità. (È vero che il !
personaggio può essere difficile da vedere a colpo d'occhio; a volte aggiungo uno spazio dopo !
per evitarlo.)
E spesso puoi evitare il problema e migliorare la chiarezza riorganizzando leggermente il codice. Ad esempio, anziché:
if (!cond) {
do_this();
}
else {
do_that();
}
potresti scrivere:
if (cond) {
do_that();
}
else {
do_this();
}
Non è sempre meglio, ma non fa male cercare opportunità dove si trova.
Riepilogo: in C e C ++, i confronti tra uguaglianza true
e stile false
pericoloso, eccessivamente prolisso e scadente. In molte altre lingue, tali confronti potrebbero non essere pericolosi, ma sono ancora troppo prolissi e di scarsa qualità.