In C e alcune lingue simili, il confronto tra espressioni booleane per l'uguaglianza in 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 un'istruzione if
. La regola C è che if (cond)
è equivalente a if (cond != 0)
- vale a dire, zero è falso e qualsiasi valore diverso da zero è vero. Se cond
è di tipo puntatore, 0
viene considerato come costante puntatore nullo; if (ptr)
significa if (ptr != NULL)
.
Questo 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 funzione isdigit()
dichiarata in <ctype.h>
restituisce un valore int
, 0
se l'argomento è una cifra, diversa da zero se non lo è. Può restituire 42
per indicare che la condizione è vera. Il confronto con 42 == true
fallirà.
Succede che 0
è l'unico valore considerato falso, quindi il confronto tra uguaglianza e false
funzionerà; if (!cond)
e if (cond == false)
fanno la stessa cosa. Ma se hai intenzione di approfittarne, devi ricordare che il confronto con false
è ok, e il confronto con true
non lo è. Peggio ancora, il confronto con true
funzionerà la maggior parte del tempo (ad esempio, l'uguaglianza e gli operatori relazionali producono sempre 0
o 1
). Ciò significa che eventuali bug introdotti usando questo ancora potrebbero essere difficili da rintracciare. (Non ti preoccupare, appariranno non appena dimostrerai il codice a un cliente importante.)
C ++ ha regole leggermente diverse; ad esempio, il suo tipo bool
è un po 'più strettamente integrato nella lingua e if (cond)
converte cond
nel tipo bool
. Ma l'effetto è (principalmente) lo stesso.
Alcuni altri linguaggi hanno quello che si potrebbe definire un booleano con un comportamento migliore, in modo che cond == true
e cond == false
(o qualsiasi altra cosa la sintassi sia) sia sicuro. Anche così, ogni lingua che ho visto ha un not
o !
operatore; è lì, quindi potresti anche usarlo. L'utilizzo di cond == false
anziché !cond
o not cond
non migliora, a mio parere, la leggibilità. (È vero che il carattere !
può essere difficile da vedere a prima vista, a volte aggiungo uno spazio dopo !
per evitare ciò.)
E spesso puoi evitare il problema e migliorare la chiarezza ridisponendo leggermente il codice. Ad esempio, anziché:
if (!cond) {
do_this();
}
else {
do_that();
}
potresti scrivere:
if (cond) {
do_that();
}
else {
do_this();
}
Questo non è sempre migliore, ma non fa male a cercare opportunità dov'è.
Riepilogo: in C e C ++, i confronti di uguaglianza con true
e false
sono pericolosi, eccessivamente prolissi e di stile scadente. In molte altre lingue, tali confronti potrebbero non essere pericolosi, ma sono ancora eccessivamente prolissi e di stile scadente.