Является ли операция "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.