Заказ булевых значений

В С++ или <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

Таким образом, любое ненулевое значение является "истинным".