conversión de bool a int

131

Qué portátil es esta conversión. ¿Puedo estar seguro de que ambas afirmaciones pasan?

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

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

No preguntes por qué. Sé que es feo. Gracias.

pic11
fuente
¿Por qué no cambias la primera expresión? Puede escribir assert(x!=0). Incluso si bool (true) convierte portable a int (1), las afirmaciones "no falsas" tienen una expresión más legible.
Harper
1
Por qué no: assert( 4 < 5);yassert(!( 4 > 5));
Martin York
44
@harper: Usar el valor requerido de una expresión de comparación es perfectamente razonable.
R .. GitHub DEJA DE AYUDAR A ICE
@ R._ Cuando la pregunta es si la conversión de bool a int da un resultado razonable, no confiaría en esto. Cuando el autor tiene dudas de que este requisito se cumpla, el lector podría tener el mismo problema. Especialmente porque el valor de x no es la condición para verificar sino solo un resultado intermedio.
Harper
3
Probablemente escribiría (4 < 5) ? 1 : 0si realmente necesito convertir un booleano a 0 o 1. Un buen compilador probablemente producirá el mismo código de máquina y es más claro para un lector humano.
ollb

Respuestas:

205
int x = 4<5;

Completamente portátil. Conforme estándar. boola la intconversión está implícito!

§4.7 / 4 del estándar C ++ dice ( Conversión integral )

Si el tipo de fuente es bool, el valor falsese convierte a cero y el valor truese convierte a uno .


En cuanto a C, por lo que yo sé que no hay boolen C. (antes de 1999) Así boolque intla conversión es relevante en C ++ solamente. En C, se 4<5evalúa como intvalor, en este caso el valor es 1, 4>5 se evaluaría como 0.

EDITAR: Jens en el comentario dijo, C99 tiene _Booltipo. booles una macro definida en el stdbool.harchivo de encabezado. truey falsetambién están definidos en macro stdbool.h.

El § 7.16 del C99 dice:

La macro se boolexpande a _Bool.

[..] trueque se expande a la constante entera 1, false que se expande a la constante entera 0, [..]

Nawaz
fuente
3
asegúrese de que haya boolen C desde 1999. Simplemente use el encabezado "stdbool.h" y esto debería incluirse.
Jens Gustedt
1
De hecho, lo comprobé en varios compiladores y parece ser portátil.
pic11
8
Independientemente de la versión del lenguaje C y la disponibilidad de bool/ _Booltype, los operadores relacionales en C producen int, no bool. Es decir, incluso en C99, los operadores relacionales todavía producen int.
ANT
51

Etiquetó su pregunta [C] y [C ++] al mismo tiempo. Los resultados serán consistentes entre los idiomas, pero la estructura de la respuesta es diferente para cada uno de estos idiomas.

En lenguaje C, sus ejemplos no tienen ninguna relación con booleso (eso también se aplica a C99). En lenguaje C, los operadores relacionales no producen boolresultados. Ambos 4 > 5y 4 < 5son expresiones que producen resultados de tipo intcon valores 0o 1. Por lo tanto, no hay "conversión de bool a int" de ningún tipo en sus ejemplos en C.

En C ++, los operadores relacionales sí producen boolresultados. boollos valores son convertibles a inttipo, con trueconversión a 1y falseconversión a 0. Esto está garantizado por el idioma.

El lenguaje PS C también tiene un tipo booleano dedicado _Bool(macro-alias como bool), y sus reglas de conversión integral son esencialmente las mismas que en C ++. Sin embargo, esto no es relevante para sus ejemplos específicos en C. Una vez más, los operadores relacionales en C siempre producen int(no bool) resultados independientemente de la versión de la especificación del lenguaje.

Hormiga
fuente
2
Así es, no hay bool en K&R C. Reetiqué mi pregunta como C99.
pic11
@ pic11: No hubo necesidad de volver a etiquetar nada. No tiene nada que ver con K&R o cualquier otra C. A pesar de que hay boolen C99, los operadores relacionales todavía producen inten C99, no bool. Entonces, si le interesan específicamente los operadores relacionales (como en sus ejemplos), el problema aún no tiene nada que ver bool.
An
Ahora lo entiendo. El resultado del operador de relación implícitamente convertible a int. Esto es cierto en C, C99 y C ++. Re-asaltado de nuevo.
pic11
3
@ pic11: No, no lo entiendes. En C, incluido C99, el resultado de un operador de comparación es un int, no un bool. No ocurre conversión.
R .. GitHub DEJA DE AYUDAR A ICE
¿Hay alguna forma conforme a los estándares a través de la cual un idioma podría tener un tipo que se comporta como boolpero no permite que se tome su dirección? Muchos sistemas integrados hacen uso de tales tipos (a menudo declarados utilizando el identificador bit). Por ejemplo, en un PIC de rango medio, if (bitVar1) bitVar2=1;serían dos instrucciones; la codificación óptima if (byteVar1) byteVar2=1;sería de al menos cuatro (en muchos compiladores, probablemente cinco). Tales tipos pueden ofrecer un gran aumento de rendimiento.
supercat
17

La sección 6.5.8.6 del estándar C dice:

Cada uno de los operadores <(menor que),> (mayor que), <= (menor o igual que) y> = (mayor o igual que) producirá 1 si la relación especificada es verdadera y 0 si es falso.) El resultado tiene el tipo int.


fuente
Gracias por la referencia Parece que cierto == 1 por razones históricas.
pic11
2

Parece que no hay ningún problema ya que el int to bool cast se realiza implícitamente. Esto funciona en Microsoft Visual C ++, GCC y el compilador Intel C ++. No hay problema en C o C ++.

Alex James
fuente
2
"Funciona en algunos casos" no es una buena manera de verificar la corrección, especialmente con versiones no especificadas de esas herramientas. Prefiero el enfoque en las otras respuestas; no pueden garantizar que una implementación particular sea correcta, pero pueden garantizar lo que hará una implementación correcta.
Matthew leyó