¿Puedo asumir (bool) true == (int) 1 para cualquier compilador de C ++?

118

¿Puedo asumir (bool)true == (int)1para cualquier compilador de C ++?

Petruza
fuente
3
Los moldes en su pregunta son redundantes, ¿deberían revertirse?
GManNickG
9
No quiere decir que sean elencos, quiere decirbool t = true; int n = 1; if (t == n) {...} ;
egrunin
7
@egrunin: Eh, pero true es un bool y 1 es un int de todos modos. :)
GManNickG
1
Bien, quise indicar el tipo de valores.
Petruza
2
(int) truees 1como un valor entero, pero algo como if (pointer)pasa por la parte de entonces si pointer != 0. Lo único que puede asumir como cierto es que false == 0, y true != 0(y se trueevalúa 1cuando se envía a int)
Luis Colorado

Respuestas:

134

Si. Los moldes son redundantes. En tu expresión:

true == 1

Se aplica la promoción integral y el valor bool se promoverá a un int y esta promoción debe producir 1.

Referencia: 4.7 [conv.integral] / 4: Si el tipo de fuente es bool... truese convierte en uno.

CB Bailey
fuente
9
@Joshua: truees una palabra clave definida por el idioma. No puede ser redefinido por una biblioteca. #defineLos s no pueden redefinir palabras clave.
jalf
21
@jalf: Los #definidos pueden definir palabras clave del sistema. La fase de preprocesamiento de la compilación de C es puramente textual y no sabe nada de palabras clave ni de la sintaxis de C en general. Sin embargo, por supuesto, casi siempre es una mala idea redefinir las palabras clave del idioma.
Dale Hagglund
2
@jalf. ¿Ellos no están? Vea gcc.gnu.org/onlinedocs/cpp/Macros.html , y al menos una de las entradas en el Concurso Internacional de Código C ofuscado, que una vez preguntó "¿Cuándo whileno toma un tiempo?" (Respuesta: cuando se necesitan dos parámetros, porque entonces esa entrada tenía #definedque hacerlo printf).
Ken Bloom
3
C99, §6.10.1 / 1 dice: "La expresión que controla la inclusión condicional debe ser una expresión constante entera, excepto que: no debe contener una conversión; los identificadores (incluidos los léxicamente idénticos a las palabras clave) se interpretan como se describe a continuación;" Aunque no se indica como permiso directo, esto claramente contempla la posibilidad de una macro que sea "léxicamente idéntica" a una palabra clave.
Jerry Coffin
2
Ah, y los #defines pueden redefinir las palabras clave. C ++ 1x causó demasiados problemas con sus nuevas palabras clave, por lo que ese requisito tuvo que eliminarse.
Joshua
18

La respuesta de Charles Bailey es correcta. La redacción exacta del estándar C ++ es (§4.7 / 4): "Si el tipo de fuente es bool, el valor falso se convierte a cero y el valor verdadero se convierte en uno".

Editar: Veo que también agregó la referencia; lo eliminaré en breve, si no me distraigo y olvido ...

Edit2: Por otra parte, probablemente valga la pena señalar que, si bien los valores booleanos en sí mismos siempre se convierten en cero o uno, una serie de funciones (especialmente de la biblioteca estándar de C) devuelven valores que son "básicamente booleanos", pero representados como ints que son normalmente solo se requiere que sea cero para indicar falso o distinto de cero para indicar verdadero. Por ejemplo, las funciones is * en <ctype.h>solo requieren cero o distinto de cero, no necesariamente cero o uno.

Si lanza eso a bool, cero se convertirá en falso y lo que no sea de cero en verdadero (como era de esperar).

Jerry Coffin
fuente
9

De acuerdo con el estándar, debe estar seguro con esa suposición. El booltipo C ++ tiene dos valores - trueyfalse con los valores correspondientes 1 y 0.

Lo que hay que tener en cuenta es mezclar boolexpresiones y variables con BOOLexpresión y variables. Este último se define como FALSE = 0y TRUE != FALSE, lo que a menudo en la práctica significa que cualquier valor diferente de 0 se consideraTRUE .

Muchos compiladores modernos emitirán una advertencia para cualquier código que implícitamente intente pasar de BOOLa boolsi el BOOLvalor es diferente de 0 o 1.

Franci Penov
fuente
3

He encontrado que diferentes compiladores devuelven resultados diferentes en verdadero. También descubrí que casi siempre es mejor comparar un bool con un bool en lugar de un int. Esos valores tienden a cambiar el valor con el tiempo a medida que su programa evoluciona y si asume verdadero como 1, puede ser mordido por un cambio no relacionado en otra parte de su código.

Michael Dorgan
fuente
3
Esta es una respuesta incorrecta para C ++, ya que truees una palabra clave de lenguaje con comportamiento definido. Si se refiere a una macro comúnmente definida como TRUE, es correcta.
David Thornley
1
Podría ser mi experiencia con los compiladores de C; he pasado mucho tiempo con ellos a lo largo de los años. Sin embargo, mi punto sobre el uso directo de expresiones matemáticas en declaraciones if se mantiene. Teníamos un código que al ver si un cambio de bit era distinto de cero en un if, entonces alguien más tomó ese mismo valor distinto de cero y asumió que era 1 y explotó las cosas. Una simple conversión a verdadero / 1 lo habría evitado.
Michael Dorgan
Yo también he visto comportamientos de este tipo. Es cierto que la última vez que lo vi fue alrededor de 1999. Estaba usando GCC. El idioma era C. Aún así, he visto tal comportamiento.
jueves