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.