Cambiare un valore bool in un valore diverso da 0 o 1?

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é truefalse .

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