Является ли операция "false <true" четко определенной?
Определяет ли спецификация С++:
- существование оператора "меньше" для булевых параметров, и если да,
- результат 4-позиционных перестановок?
Другими словами, являются ли результаты следующих операций, определенных спецификацией?
false < false
false < true
true < false
true < true
В моей настройке (Centos 7, gcc 4.8.2) код ниже выплевывает то, что я ожидаю (учитывая, что C-история представляет false как 0 и true как 1):
false < false = false
false < true = true
true < false = false
true < true = false
В то время как я уверен, что большинство (все?) компиляторы будут давать одинаковый результат, это законодательно закреплено спецификацией С++? Или является запутывающим, но компилятор, совместимый с спецификациями, позволил решить, что true меньше false?
#include <iostream>
const char * s(bool a)
{
return (a ? "true" : "false");
}
void test(bool a, bool b)
{
std::cout << s(a) << " < " << s(b) << " = " << s(a < b) << std::endl;
}
int main(int argc, char* argv[])
{
test(false, false);
test(false, true);
test(true, false);
test(true, true);
return 0;
}
Ответы
Ответ 1
TL; ДР:
Операции хорошо определены в соответствии со стандартом С++.
Подробнее
Мы можем видеть, что, перейдя в проект стандарта С++ раздел 5.9
Реляционные операторы, которые говорят (акцент мой вперед):
Операторы должны иметь арифметические, перечисление или указатель типа, или введите std:: nullptr_t. Операторы < (меньше), > (больше), <= (меньше или равно), и >= (больше или равно) все дают false или true. Тип результата: bool
и bools являются арифметическими типами из 3.9.1 Основные типы
Типы bool, char, char16_t, char32_t, wchar_t, и целые типы с подписью и без знака являются коллективными называется интегральными типами.
и
Интегральные и плавающие типы совместно называются арифметическими типы.
и true
и false
являются булевыми литералами из 2.14.6
булевых литералов:
boolean-literal:
false
true
Возвращаясь к разделу 5.9
, чтобы дальше видеть механику реляционных операторов, он говорит:
Обычные арифметические преобразования выполняются в операндах арифметического или перечисляемого типа.
обычные арифметические преобразования рассматриваются в разделе 5
, в котором говорится:
В противном случае интегральные акции (4.5) должны выполняться на обоих операндах
и раздел 4.5
говорит:
Значение типа bool может быть преобразовано в prvalue типа int, при этом false становится равным нулю и true став одним.
и поэтому выражения:
false < false
false < true
true < false
true < true
используя следующие правила:
0 < 0
0 < 1
1 < 0
1 < 1
Ответ 2
Булевы значения подчиняются обычным целым рекламным акциям, причем false
определяется как 0
и true
, определяемый как 1
. Это делает все сравнения хорошо определенными.
Ответ 3
В соответствии со стандартом С++ (5.9 Реляционные операторы)
2 Обычные арифметические преобразования выполняются на операндах арифметический или перечисляемый тип.
и
1... Тип результата: bool.
и (3.9.1 Основные типы)
6 Значения типа bool являются либо истинными, либо ложными .49 [Примечание: нет подписанные, неподписанные, короткие или длинные типы или значения bool. -end note] Значения типа bool участвуют в интегральных акциях (4.5).
и (4.5 Интегральные акции)
6 Значение prool типа bool может быть преобразовано в prvalue типа int, с false, становящимся нулевым и истинным, становясь одним.
Итак, во всех ваших примерах true преобразуется в int 1, а false преобразуется в int 0
Эти выражения
false < false
false < true
true < false
true < true
полностью эквивалентны
0 < 0
0 < 1
1 < 0
1 < 1
Ответ 4
Boolean false
эквивалентно int 0
, а boolean true
эквивалентно int 1
.
Таким образом, это объясняет, почему выражение false < true
= > 0 < 1
является единственным, которое возвращает true
.