Posso presumere (bool) true == (int) 1 per qualsiasi compilatore C ++?


118

Posso presumere (bool)true == (int)1per qualsiasi compilatore C ++?


3
I cast nella tua domanda sono ridondanti, dovrebbero essere invertiti?
GManNickG

9
Non intende che siano cast, intendebool t = true; int n = 1; if (t == n) {...} ;
Egrunin

7
@egrunin: Eh, ma true è un bool e 1 è comunque un int. :)
GManNickG

1
Esatto, volevo indicare il tipo di valori.
Petruza

2
(int) trueè 1come un valore intero, ma qualcosa come if (pointer)passa attraverso la parte then if pointer != 0. L'unica cosa che puoi presumere come vera è che false == 0, e true != 0(e truevaluta 1quando viene lanciato int)
Luis Colorado,

Risposte:


134

Sì. I cast sono ridondanti. Nella tua espressione:

true == 1

Si applica la promozione integrale e il valore bool verrà promosso a an inte questa promozione deve restituire 1.

Riferimento: 4.7 [conv.integral] / 4: Se il tipo di sorgente è bool... trueviene convertito in uno.


9
@ Joshua: trueè una parola chiave definita dalla lingua. Non può essere ridefinito da una libreria. #defineNon è consentito ridefinire le parole chiave.
jalf

21
@jalf: i # define sono effettivamente autorizzati a definire le parole chiave di sistema. La fase di pre-elaborazione della compilazione del C è puramente testuale e non conosce parole chiave o sintassi C in generale. Tuttavia, è, ovviamente, quasi sempre una cattiva idea ridefinire le parole chiave della lingua.
Dale Hagglund,

2
@jalf. Loro non sono? Vedi gcc.gnu.org/onlinedocs/cpp/Macros.html e almeno una delle voci del Concorso Internazionale sul Codice C offuscato, che una volta chiedeva "Quando non whileci vuole un po 'di tempo?" : (Risposta quando prende due parametri, perché allora che l'ingresso era #defineda printf.)
Ken Bloom

3
C99, §6.10.1 / 1 dice: "L'espressione che controlla l'inclusione condizionale deve essere un'espressione costante intera eccetto che: non deve contenere un cast; gli identificatori (inclusi quelli lessicalmente identici alle parole chiave) sono interpretati come descritto di seguito;" Sebbene non sia dichiarato come permesso diretto, questo contempla chiaramente la possibilità di una macro "lessicalmente identica" a una parola chiave.
Jerry Coffin

2
Oh, e #defines possono ridefinire le parole chiave. C ++ 1x causava troppi problemi con le sue nuove parole chiave, quindi quel requisito doveva essere rimosso.
Joshua

18

La risposta di Charles Bailey è corretta. La formulazione esatta dello standard C ++ è (§4.7 / 4): "Se il tipo di origine è bool, il valore false viene convertito in zero e il valore true viene convertito in uno."

Modifica: vedo che ha aggiunto anche il riferimento: lo cancellerò a breve, se non mi distraggo e dimentico ...

Edit2: Poi di nuovo, vale probabilmente la pena notare che mentre i valori booleani si convertono sempre in zero o uno, un certo numero di funzioni (specialmente dalla libreria standard C) restituiscono valori che sono "fondamentalmente booleani", ma rappresentati come ints che sono normalmente richiesto solo di essere zero per indicare falso o diverso da zero per indicare vero. Ad esempio, le funzioni is * <ctype.h>richiedono solo zero o diverso da zero, non necessariamente zero o uno.

Se lo lanci a bool, zero verrà convertito in falso e diverso da zero in vero (come ti aspetteresti).


9

Secondo lo standard, dovresti essere al sicuro con questo presupposto. Il booltipo C ++ ha due valori truee falsecon i valori corrispondenti 1 e 0.

La cosa a cui prestare attenzione è mescolare boolespressioni e variabili con BOOLespressioni e variabili. Quest'ultimo è definito come FALSE = 0e TRUE != FALSE, che abbastanza spesso in pratica significa che viene considerato qualsiasi valore diverso da 0 TRUE.

Molti compilatori moderni emetteranno effettivamente un avviso per qualsiasi codice che tenti implicitamente di eseguire il cast da BOOLa boolse il BOOLvalore è diverso da 0 o 1.


3

Ho trovato diversi compilatori che restituiscono risultati diversi su true. Ho anche scoperto che è quasi sempre meglio confrontare un bool con un bool invece di un int. Questi int tendono a cambiare valore nel tempo man mano che il tuo programma si evolve e se assumi vero come 1, puoi essere morso da una modifica non correlata altrove nel tuo codice.


3
Questa è una risposta errata per C ++, così come trueuna parola chiave del linguaggio con un comportamento definito. Se fai riferimento a una macro definita comunemente come TRUE, è corretto.
David Thornley,

1
Potrebbe essere la mia esperienza con i compilatori C: ho passato molto tempo con loro nel corso degli anni. Il mio punto sull'utilizzo diretto di espressioni matematiche nelle istruzioni if ​​è valido. Avevamo un codice che vedeva se un bit shift era diverso da zero in un if, qualcun altro prendeva lo stesso valore diverso da zero e presumeva che fosse 1 e faceva saltare in aria. Una semplice conversione a true / 1 l'avrebbe impedito.
Michael Dorgan

Anch'io ho visto comportamenti di questo tipo. Certo, l'ultima volta che l'ho visto era circa nel 1999. Stavo usando GCC. La lingua era C. Tuttavia, ho davvero visto un simile comportamento.
gio
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.