Ho il codice seguente:
#include int main() { bool b; // Set b to 123 char *p = (char*)&b; *p = 123; // Check if b is considered to be true if (b == true) printf("b is true"); return 0; }
b
non è considerato true
, quindi cosa vuol dire esattamente true
, true
è uguale a 1
?
Modifica: ho dimenticato di usare Visual C ++.
bool b; // Set b to 123 char *p = (char*)&b; *p = 123;
Lo standard C ++ non specifica come viene memorizzato bool
… ad esempio, è del tutto legale che un compilatore usi un byte e un altro ne usi quattro. Inoltre, un compilatore potrebbe memorizzare dire 0
per false
e all-bits-on per true
e un altro 0
e 1
o qualsiasi altro valore. Tutto ciò che importava era che, quando usato in un contesto booleano, la logica funzioni correttamente e che quando viene convertita in o da un int
:
int(b)
è 1
se b
è true
e 0
se b
è false
e
bool(n)
è true
se-e-solo-se n
non era 0
.
Per questo motivo, il carattere al più basso indirizzo di memoria nella rappresentazione bool
può o non può essere consultato quando si verifica il valore del booleano: potrebbe essere il codice generato da un compilatore usa un int
quattro byte che viene letto quindi ha solo il minimo test significativo su bit o byte, che – a seconda dell’endianità – potrebbe non essere stato toccato da *p = 123
. Allo stesso modo, il compilatore potrebbe leggere il valore in un registro intero con segno e testare la negatività (aspettandosi un valore all-bits-on quando è true
), che potrebbe anche fallire anche se *p = 123
fosse stato scritto nell’unico o più significativo byte.
Di conseguenza – anche se non c’era nient’altro in gioco – la riga sottostante potrebbe non riportare “b is true” …
// Check if b is considered to be true if (b == true) printf("b is true");
… ma quel test è ulteriormente incrinato da …
possibilmente leggendo da altri byte nella rappresentazione bool
che non è stata inizializzata (le letture della memoria non inizializzate hanno un comportamento non definito)
giocherellare con il valore bool
da solo ha intrinsecamente un “comportamento indefinito”; in termini di “scrittura binaria” nella memoria del bool
, solo una copia byte per byte completa da un altro bool
opportunamente inizializzato è garantita per lasciare che questo bool
sia uno stato utilizzabile.
C ++ 11 dice (3.9 “Tipi” [basic.types]):
La rappresentazione del valore di un object è l’insieme di bit che contengono il valore di tipo T. Per i tipi banalmente copiabili, la rappresentazione del valore è un insieme di bit nella rappresentazione dell’object che determina un valore, che è un elemento discreto di un’implementazione- insieme definito di valori
E (3.9.1 “Tipi fondamentali” [basic.fundamental]):
Per i tipi di carattere, tutti i bit della rappresentazione dell’object partecipano alla rappresentazione del valore. Per i tipi di caratteri senza segno, tutti i possibili schemi di bit della rappresentazione del valore rappresentano numeri. Questi requisiti non valgono per altri tipi .
…
I valori di tipo bool sono o veri o falsi
E infine, 5 “Expressions” [expr] dice:
Se durante la valutazione di un’espressione, il risultato non è definito matematicamente o non rientra nell’intervallo di valori rappresentabili per il suo tipo, il comportamento non è definito.
Quello che sta accadendo è che quando scrivi il valore 123 nella memoria che l’object bool
occupa (tramite char* p
), stai scrivendo qualcosa che non può essere rappresentato nella “rappresentazione del valore” dell’object bool
. Quindi, quando successivamente accedete a quell’object attraverso il lvalue b
il programma mostra un comportamento indefinito e avete un object bool
che non è né true
né false
.
E per rispondere alla tua domanda su quale sia il valore di true
: lo standard non specifica mai realmente. Specifica che il true
è uno dei due valori che un tipo di bool
può rappresentare (l’altro è false
ovviamente). Lo standard specifica anche che true
converte prontamente in 1 e viceversa, 1 converte prontamente in true
. Queste conversioni avvengono in modo così naturale e facile che penso che quasi tutti considerano true
il valore 1.
Una cosa da ricordare è che quasi ogni valore integrale non zero si converte prontamente in true
– non solo 1. Tuttavia ciò non accade nel tuo esempio per il valore 123 perché in quell’espressione viene scritto in un lvalue con tipo char
quindi nessuna conversione a bool
verifica.
true
mezzo 1
Ma 123 è anche considerato vero (generalmente tutti gli interi tranne zero)
se dici
if (b) printf("b is true");
è necessario ottenere l’output b is true