conversione da bool a int


131

Quanto è portatile questa conversione. Posso essere sicuro che entrambe le affermazioni passino?

int x = 4<5;
assert(x==1);

x = 4>5;
assert(x==0);

Non chiedere perché. So che è brutto. Grazie.


Perché non cambi la prima espressione? Puoi scrivere assert(x!=0). Anche se bool (true) converte il portatile in int (1), le affermazioni "non false" hanno un'espressione più leggibile.
Harper il

1
Perché no: assert( 4 < 5);eassert(!( 4 > 5));
Martin York,

4
@harper: l'utilizzo del valore richiesto di un'espressione di confronto è perfettamente ragionevole.
R .. GitHub smette di aiutare ICE il

@ R._ Quando la domanda è se la conversione da bool-a-int a dare un risultato ragionevole, non vorrei fare affidamento su questo. Quando l'autore dubita che questo requisito sia soddisfatto, il lettore potrebbe avere lo stesso problema. Soprattutto perché il valore di x non è la condizione da verificare ma solo un risultato intermedio.
Harper

3
Probabilmente scriverei (4 < 5) ? 1 : 0se avessi davvero bisogno di convertire un valore booleano in 0 o 1. Un buon compilatore produrrà probabilmente lo stesso codice macchina ed è più chiaro per un lettore umano.
ollb,

Risposte:


205
int x = 4<5;

Completamente portatile. Conforme allo standard. boolalla intconversione è implicito!

§4.7 / 4 dallo standard C ++ dice ( Conversione integrale )

Se il tipo di origine è bool, il valore falseviene convertito in zero e il valore trueviene convertito in uno .


Per quanto riguarda la C, per quanto ne so non c'è boolin C. (prima del 1999) Così boolalla intconversione è rilevante in C ++ solo. In C, 4<5valuta il intvalore, in questo caso il valore è 1, 4>5 valuterebbe a 0.

EDIT: Jens nel commento ha detto, C99 ha _Booltipo. boolè una macro definita nel stdbool.hfile di intestazione. truee falsesono anche macro definite in stdbool.h.

§ 7.16 da C99 dice,

La macro si boolespande in _Bool.

[..] trueche si espande alla costante intera 1, false che si espande alla costante intera 0, [..]


3
certo che esiste boolin C dal 1999. Basta usare l'intestazione "stdbool.h" e questo dovrebbe essere incluso.
Jens Gustedt,

1
In effetti, l'ho controllato su diversi compilatori e sembra essere portatile.
11

8
Indipendentemente dalla versione del linguaggio C e dalla disponibilità di bool/ _Booltipo, gli operatori relazionali in C producono int, no bool. Vale a dire anche nel C99, gli operatori relazionali continuano a produrre int.
An

51

Hai taggato la tua domanda [C] e [C ++] contemporaneamente. I risultati saranno coerenti tra le lingue, ma la struttura della risposta è diversa per ciascuna di queste lingue.

Nel linguaggio C i tuoi esempi non hanno alcuna relazione bool(vale anche per C99). In linguaggio C gli operatori relazionali non producono boolrisultati. Entrambi 4 > 5e 4 < 5sono espressioni che producono risultati di tipo intcon valori 0o 1. Quindi, non c'è "conversione da bool a int" di alcun tipo nei tuoi esempi in C.

In C ++ gli operatori relazionali producono effettivamente boolrisultati. booli valori sono convertibili in inttipo, con trueconversione 1e falseconversione in 0. Questo è garantito dalla lingua.

Il linguaggio PS C ha anche un tipo booleano dedicato _Bool(macro-aliasing as bool) e le sue regole di conversione integrale sono essenzialmente le stesse di C ++. Tuttavia, ciò non è rilevante per i tuoi esempi specifici in C. Ancora una volta, gli operatori relazionali in C producono sempre int(non bool) risultati indipendentemente dalla versione della specifica del linguaggio.


2
Esatto, non c'è bool in K&R C. Ho ricodificato la mia domanda come C99.
11

@ pic11: non è stato necessario ripagare nulla. Non ha nulla a che fare con K&R o altri C. Anche se c'è boolin C99, gli operatori relazionali continuano a produrre intin C99, no bool. Quindi, se sono gli operatori relazionali a cui sei interessato (come nei tuoi esempi), il problema non ha ancora nulla a che fare bool.
An

Ora capisco. Il risultato dell'operatore di relazione implicitamente convertibile in int. Questo è vero in C, C99 e C ++. Nuovo bersaglio.
11

3
@ pic11: No, non capisci. In C, incluso C99, il risultato di un operatore di confronto è un int, non un bool. Non si verifica alcuna conversione.
R .. GitHub FERMA DI AIUTARE ICE

Esiste un modo conforme agli standard attraverso il quale una lingua potrebbe avere un tipo che si comporta come boolma non consente di prendere il suo indirizzo? Molti sistemi integrati utilizzano tali tipi (spesso dichiarati utilizzando l'identificatore bit). Ad esempio un PIC di fascia media, if (bitVar1) bitVar2=1;sarebbero due istruzioni; la codifica ottimale if (byteVar1) byteVar2=1;sarebbe almeno quattro (su molti compilatori, probabilmente cinque). Tali tipi possono quindi offrire un notevole incremento delle prestazioni.
supercat

17

La sezione 6.5.8.6 della norma C dice:

Ciascuno degli operatori <(minore di),> (maggiore di), <= (minore o uguale a) e> = (maggiore o uguale a) restituisce 1 se la relazione specificata è vera e 0 se è false.) Il risultato ha tipo int.


Grazie per il riferimento. Sembra che true == 1 per motivi storici.
11

2

Sembra che non ci siano problemi poiché l'int di booling cast è fatto implicitamente. Funziona con i compilatori Microsoft Visual C ++, GCC e Intel C ++. Nessun problema in C o C ++.


2
"Funziona in alcuni casi" non è un buon modo per verificare la correttezza, soprattutto con le versioni non specificate di tali strumenti. Preferisco l'approccio nelle altre risposte; non possono garantire che una particolare implementazione sia corretta, ma possono garantire che cosa farà una corretta implementazione.
Matteo Leggi
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.