YES, TRUE, BOOL, e boolean… Quali usare? Ecco le differenze

Potrebbe non essere subito chiaro che in Objective-C il “tipo” BOOL non è in realtà un vero tipo booleano (che ammette 0 o 1). Si tratta di un retaggio del linguaggio C originale, che non ha un tipo intrinseco booleano (il compilatore iPhone GCC C supporta ISO C99 che definisce un tipo bool).

Per chiarire, nel file di sistema di intestazione objc.h si può vedere quanto segue:

typedef signed char BOOL;

Da questo è chiaro che BOOL è realmente un tipo signed char. Questo ha alcune implicazioni quando cerchiamo di assegnare il “YES” e “NO” a valori che sono in genere assegnati alle variabili di “tipo” BOOL . Se guardiamo un po’ più in basso nel objc.h verrà visualizzato quanto segue:

#define YES (BOOL)1
#define NO (BOOL)0

Allora, qual è il problema con BOOL e YES? In poche parole, il problema è che le variabili di tipo BOOL possono contenere valori diversi da YES e NO. Al contrario di NO che non costituisce un problema poiché NO == 0 == NO , ma a confronto, per YES può essere difficile, soprattutto se si fa affidamento sul codice di terze parti. Considerate questo:

BOOL b = 37;
if (b) {
 printf("b è YES!\n");
}
if (b != YES) {
 printf("b non è YES!\n");
}

L’output potrebbe essere il seguente:

b è YES!
b non è YES!

Il problema sorge perché il confronto diretto con YES fallirà quando il valore di un tipo BOOL è diverso da zero e diverso da 1.

Si noti che ObjC (supponendo che l’impostazione predefinita C99 sia attivata) supporta anche il bool come tipo di dato, che è un tipo intrinseco booleano e può essere solo impostato su true o false. Un modo sicuro per la conversione tra BOOL e bool è il seguente:

// da BOOL a bool
bool b = myBOOL ? true : false;
// e ritorno
myBOOL = b ? YES : NO;

La morale della storia è quello di evitare i confronti diretti tra tipo BOOL e costanti YES.

Buon 2013!