c++ - tipo - Ordenación de valores booleanos.
tipo bool (7)
Aquí hay una explicación, no he comprobado con el estándar sin embargo. De sus experimentos, parece que el operador "<" no está definido para valores booleanos. Lo que se compara son las entradas sin firmar a las que se convierten los booleanos. En teoría, podría ser posible que el estándar no garantice que todos los booleanos "verdaderos" se conviertan al mismo valor. Y -1 se convierte en el int sin signo más grande.
Como otro experimento, el siguiente código
#include <iostream>
int main()
{
std::cout<< (((bool)1) == true) << "/n";
std::cout<< (((bool)2) == true) << "/n";
std::cout<< (((bool)0) == false) << "/n";
std::cout<< (((bool)1) == false) << "/n";
return 0;
}
impresiones 1 1 1 0
Así que cualquier valor distinto de cero es "verdadero".
Bajo C ++ o <stdbool.h>
de C99, ¿cómo se define el operador <
para valores booleanos?
Alternativamente, explica el comportamiento de este código:
#ifndef __cplusplus
#include <stdbool.h>
#endif
#include <stdio.h>
int main() {
bool b = -1;
if(b < true) {
printf("b < true/n");
}
if(b < false) {
printf("b < false/n");
}
if(true < false) {
printf("true < false/n");
}
if(false < true) {
printf("false < true/n");
}
}
Bajo MSVC versión 10, compilado como código C ++, GCC 4.6.3-ubuntu5 compilado como código C y G ++ 4.6.3-1ubuntu5 compilado como código C ++, todo lo que obtiene es
false < true
Es decir, las siguientes desigualdades son todas false
:
(bool)-1 < true
(bool)-1 < false
true < false
Y lo siguiente es true
:
false < true
En C ++ (y sospecho que en C también), las comparaciones de bool
exactamente como si false
fuera 0
y true
fuera 1
. Y si el tipo es bool
, no es posible ningún otro valor que no sea true
o false
.
Al comparar bool
con otros tipos numéricos, se convertirá a int
, nuevamente con la conversión false
a 0
y la conversión true
a 1
.
Edición: tanto C ++ como stdbool.h
en C99 también obligan a los valores booleanos a ser 0 (falso) o 1 (verdadero) - bool b = -1;
establece el valor de b
en 1. Dado que 1 < 1
y 1 < 0
son falsos, las desigualdades en la pregunta son correctas.
Edición: (por James) Excepto que la edición anterior no es realmente correcta, al menos para C ++. Un bool
no tiene un valor de 0 o 1, tiene un valor de false
o true
. Solo cuando se promueve a int
la conversión crea los valores de 0
y 1
.
Y, como ha señalado Konrad, no hay comparación de valores bool
. Las "conversiones aritméticas habituales" se producen para los operadores de comparación, lo que significa una promoción integral en ambos operandos, lo que significa que bool
convierte a int
(al igual que char
o short
... o una enumeración).
Todo lo cual es bastante técnico. En la práctica, puede recordar que false
< true
, o puede considerar que false
es 0 y true
es 1, lo que más le convenga. Lo único importante que hay que recordar es que un bool
puede tener otros valores.
(Curiosamente, no creo que los patrones de bits de un bool
sean impuestos por el estándar. Una implementación podría usar los patrones de bits 0x55
y 0xAA
, por ejemplo, siempre que todas las conversiones a un tipo integral dieran 0 y 1, conversión bool
siempre dio el valor apropiado, etc. Incluyendo cero inicialización de variables estáticas.)
Y una nota final: bool b = -1;
establece b
a -1 != 0
(que es true
, no 1
, pero, por supuesto, true
se convertirá a 1
en cualquier contexto numérico.
Esto tiene perfecto sentido. El tipo integral => bool conversion es efectivamente b = i != 0
. Para hacer la comparación <
promueve el bool to int por la regla false => 0 y true => 1. En tu primer caso, -1
será igual a verdadero, y ambos se promoverán a 1, por lo que es falso. Obviamente, 1 nunca es menor que 0 para el segundo y tercer caso, mientras que 0 < 1
en el último caso.
Los valores booleanos se ordenan de manera tal que false
es más pequeño que true
. De acuerdo con el estándar, un bool
solo puede contener dos valores: true
y false
, por lo que las conversiones en (bool)-1
deberían haber sido true
(ya que todos los valores que no son 0 cuando se convierten a bool son true
). Ese es el comportamiento en clang y g ++ - 4.7.
La comparación real (creo) se realiza en int
vez que se promueve el bool
, y parece que los compiladores que probaste evitaron el paso intermedio de conversión a través de bool y solo promovieron el valor real del bool
.
Para C ++ simplemente false
< true
Para C es más difícil de responder. Veo
typedef char _Bool; /* For C compilers without _Bool */
typedef char _Bool; /* For C compilers without _Bool */
en mi stdbool.h
Parece que si el compilador soporta _Bool
, funciona como en C ++ y se convierte automáticamente a 0/1, pero si no debería funcionar como char y será b < true
, b < false
si char está firmado
Para mí (int) (bool) -1 es 1 incluso en C, por lo que bool
se define como no char
bool parece definirse como un tipo entero (con signo), falso es 0, cero es 1. Esto explica por qué verdadero> falso (1> 0) es verdadero.
Además, comparar -1 con un número sin signo hace que -1 se convierta en unsigned, y en su plataforma esto causa un desbordamiento de enteros, lo que resulta en UINT_MAX (o cualquier tipo que se haya tipificado como bool). Esto ahora explica por qué las siguientes expresiones eran falsas:
((bool)-1) < true i. e. UINT_MAX < 1
((bool)-1) < false i. e. UINT_MAX < 0
true < false i. e. 1 < 0
operador> y <se basan en esto:
true == (1)
false == (0)
esto es falso: (bool) -1 <verdadero (bool) -1 <falso debido a la aritmética variable en bool b = -1;