bool operator ++ and -

Сегодня, когда я писал код Visual C ++, я натолкнулся на кое-что, что меня удивило. Кажется, C ++ поддерживает ++ (приращение) для bool, но не - (декремент). Это просто случайное решение, или за этим стоит какая-то причина?

Это компилируется:

static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
    hMod = LoadLibrary("xxx");

Это не так:

static HMODULE hMod = NULL;
static bool once = true;
if (once--)
    hMod = LoadLibrary("xxx");
101
задан Donald Duck 10 February 2017 в 20:43
поделиться

3 ответа

Это происходит из истории использования целочисленных значений в качестве логических.

Если x - это int , но я использую его как логическое значение согласно if (x) ... , то увеличение будет означать, что все его значение истинности перед операцией, оно будет иметь значение истинности истина после него (исключение переполнения).

Однако невозможно предсказать результат - , зная только значение истинности x , так как это может привести к ложному (если интегральное значение равно 1) или истина (если интегральное значение - любое другое - в частности, это включает 0 [ ложь ] и 2 или более [ истина ]) .

Таким образом, сокращенный вариант ++ работал, а - - нет.

++ разрешено в bools для совместимости с этим, но его использование не рекомендуется в стандарте.


Предполагается, что я только использую x как логическое значение, что означает, что переполнение не может произойти, пока я не выполню ++ достаточно часто, чтобы вызвать переполнение само по себе. Даже с char в качестве используемого типа и CHAR_BITS чем-то низким, например, 5, это 32 раза, прежде чем это больше не работает (это все еще достаточный аргумент, поскольку это плохая практика, я не защищаю эту практику , просто объясняя, почему это работает) для 32-битного int нам, конечно, придется использовать ++ 2 ^ 32 раза, прежде чем это станет проблемой. С - , хотя это приведет только к false , если я начал со значения 1 для true или начал с 0 и использовал ++ ровно один раз раньше.

Это другое дело, если мы начнем со значения, которое всего на несколько единиц ниже 0.В самом деле, в таком случае мы могли бы захотеть, чтобы ++ в конечном итоге приводило к значению false , например:

int x = -5;
while(++x)
  doSomething(x);

Однако в этом примере x рассматривается как int везде, кроме условного, поэтому он эквивалентен:

int x = -5;
while(++x != 0)
  doSomething(x);

Что отличается от использования только x в качестве логического.

89
ответ дан 24 November 2019 в 04:44
поделиться

ANSI ISO IEC 14882 2003 (c ++ 03):

5.2.6-2

Операнд постфикса - это уменьшается аналогично постфиксу ++ оператор, за исключением того, что операнд не должен иметь тип bool. [Примечание: для приращение и уменьшение префикса, см. 5.3.2. ]

И неудивительно ...

5.3.2-2

Операнд префикса - изменен путем вычитания 1. Операнд должен не относиться к типу bool. Требования на операнде префикса - и свойства его результата иначе такие же, как у префикса ++. [Примечание: Для постфиксного инкремента и декремента, см. 5.2.6. ]

Также в 5.6.2-1 и 5.3.2-1 упоминается, что ++ для bools должно быть истинным, а в Приложении D-1 сказано, что ++ для bools устарело.

30
ответ дан 24 November 2019 в 04:44
поделиться

По историческим причинам это было поддержано. Но учтите, что ... Использование операнда типа bool с оператором ++ не рекомендуется, см. Раздел 5.3.2 в стандарте C ++ (n3092)

5.3.2 Увеличение и уменьшение [expr.pre.incr]

  • операнд префикса ++ изменен добавив 1, или установите значение true, если это bool (это использование не рекомендуется). В операнд должен быть изменяемым значением. Тип операнда должен быть арифметический тип или указатель на полностью определенный тип объекта. В результат - обновленный операнд; это lvalue, и это битовое поле, если операнд - битовое поле. Если x равно не типа bool, выражение ++ x эквивалентно x + = 1 [Примечание: см. обсуждение сложения (5.7) и операторы присваивания (5.17) для информация о конверсиях. - конец записки ]
  • Операнд префикса - изменен путем вычитания 1. Операнд должен не относиться к типу bool. Требования на операнде префикса - и свойства его результата в остальном такие же, как у префикса ++.
9
ответ дан 24 November 2019 в 04:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: