Заказ булевых значений
В С++ или <stdbool.h>
из C99, как определяется меньше чем оператор <
для булевых значений?
В качестве альтернативы объясните поведение этого кода:
#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");
}
}
В MSVC версии 10, скомпилированном как код С++, GCC 4.6.3-ubuntu5 скомпилирован как код C и g++ 4.6.3-1ubuntu5, скомпилированный как код С++, все, что вы получаете, это
false < true
Таким образом, следующие неравенства: false
:
(bool)-1 < true
(bool)-1 < false
true < false
И ниже true
:
false < true
Ответы
Ответ 1
В С++ (и я подозреваю и в C), bool
сравните точно так, как если бы
false
были 0
и true
были 1
. И если тип bool
, no
возможны значения, отличные от true
и false
.
При сравнении bool
с другими числовыми типами он преобразуется в int
,
снова с false
преобразованием в 0
и true
преобразование в 1
.
Изменить: Оба С++ и stdbool.h
в C99 также заставляют логические значения быть либо 0 (false), либо 1 (true) - bool b = -1;
устанавливает значение b
равным 1. Поскольку 1 < 1
и 1 < 0
оба ложны, то неравенства в вопросе правильны.
Изменить: (Джеймсом) За исключением того, что приведенное выше изменение не совсем корректно, на
для С++. A bool
не имеет значения 0 или 1, оно имеет значение
от false
или true
. Это только тогда, когда ему повышается int
, что
преобразование создает значения 0
и 1
.
И как указал Конрад, нет никакого сравнения значений bool
.
"Обычные арифметические преобразования" встречаются для операторов сравнения,
что означает интегральное продвижение по обоим операндам, что означает
bool
преобразуется в int
(как и char
или short
... или перечисление).
Все это довольно технично. На практике вы можете помнить, что
< t21 < true
, или вы можете считать, что false
равно 0 и true
равно 1,
что лучше всего подходит для вас. Важно помнить только о том, что
что a bool
не может иметь других значений.
(Интересно, я не думаю, что битовые шаблоны a bool
установленных стандартом. Реализация может использовать битовые шаблоны
0x55
и 0xAA
, например, если все преобразования в
интегральный тип дал 0 и 1, преобразование в bool
всегда давало
соответствующее значение и т.д. Включая нулевую инициализацию статического
переменные.)
И последнее замечание: bool b = -1;
устанавливает b
в -1 != 0
(что
true
, а не 1
, но, конечно, true
преобразуется в 1
в любом
числовой контекст.
Ответ 2
Это имеет смысл. Интегральное преобразование типа = > bool эффективно b = i != 0
. Чтобы выполнить сравнение <
, он продвигает bool до int по правилу false = > 0 и true = > 1. В вашем первом случае -1
будет равным true, и оба будут продвигаться до 1, так что это ложь. Очевидно, что 1 не меньше 0 для второго и третьего случаев, а 0 < 1
в последнем случае.
Ответ 3
Булевы значения упорядочены так, что false
меньше, чем true
. В соответствии со стандартом, bool
может содержать только два значения: true
и false
, поэтому преобразования в (bool)-1
должны были дать true
(поскольку все значения, отличные от 0, если они были преобразованы в bool, равны true
). Это поведение в clang и g++ - 4.7.
Фактическое сравнение (я считаю) выполняется на int
после продвижения bool
, и кажется, что компиляторы, которые вы тестировали, избегали промежуточного шага преобразования через bool и просто повышали фактическое значение bool
.
Ответ 4
Оператор > и < основываясь на этом:
true == (1)
false == (0)
это значение false: (bool) -1 < правда (bool) -1 < ложный
из-за скользящей арифметики в bool b = -1;
Ответ 5
bool представляется как целочисленный тип (подписанный), false - 0, ноль равен 1. Это объясняет, почему true > false (1 > 0) истинно.
Кроме того, сравнение -1 с неподписанным числом делает -1 отличным для unsigned, а на вашей платформе это приводит к переполнению целых чисел, в результате получается UINT_MAX (или какой бы тип bool не был указан). Это теперь объясняет, почему следующие выражения были ложными:
((bool)-1) < true i. e. UINT_MAX < 1
((bool)-1) < false i. e. UINT_MAX < 0
true < false i. e. 1 < 0
Ответ 6
Только для С++ false
< true
Для C сложнее ответить. Я вижу
typedef char _Bool; /* For C compilers without _Bool */
в моем stdbool.h
Кажется, что если поддержка компилятора _Bool
, она работает как на С++ и автоматически преобразуется в 0/1, но если нет, она должна работать как char, и это будет b < true
, b < false
if char подписан
Для меня (int) (bool) -1 равно 1 даже в C, поэтому bool
определяется как не char
Ответ 7
Вот объяснение, однако я не проверил со стандартом.
Из ваших экспериментов кажется, что "<" оператор не определен для булевых значений. То, что сравнивается, - это unsigned ints, в которые преобразуются логические элементы. Теоретически возможно, что стандарт не гарантирует, что все "истинные" булевы преобразуются в одно и то же значение. И -1 преобразуется в наибольший беззнаковый int.
В качестве другого эксперимента следующий код
#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;
}
печатает 1 1 1 0
Таким образом, любое ненулевое значение является "истинным".