Использует ли побитовый оператор (~) для булевых значений Undefined Поведение?

Если программа на С++ применяет побитовое, а не оператор (~) к логическому значению, вызывает ли это вызов Undefined Behavior?

например. является ли следующая программа корректной?

bool f = false;
bool f2 = ~f;    // is f2 guaranteed to be true, or is this UB?
bool t = true;
bool t2 = ~t;    // is t2 guaranteed to be false, or is this UB?

(Да, я знаю, что есть оператор!, который лучше подходит для такого рода вещей, для целей этого вопроса мы будем игнорировать его существование;))

Ответ 1

5.3.1/10 Операнд ~ должен иметь тип перечисления с интегральной или непроверенной информацией; результат является дополнением к его операнду. Выполняются интегральные рекламные акции. [акцент мой]

4.5/6 Значение типа bool может быть преобразовано в prvalue типа int, при этом false станет равным нулю, а true станет единым.

4.5/7 Эти преобразования называются интегральными акциями.

Итак, ~false - это int с битовой паттерной, состоящей из всех единиц - одно дополнение к битовой схеме, представляющей 0, а именно все нули (по требованию 3.9.1/7. ) Аналогично, ~true является int, что одно дополнение к битовому представлению 1, а именно, все единицы с наименьшим значащим битом нуль. Оба эти значения будут оцениваться в true в булевом контексте.

Ответ 2

Арифметические операторы выполняют интегральные продвижения по их операнду. В частности, [expr.unary.op]/9 говорит, что это происходит и для ~.

Итак, ~t совпадает с ~1. Это дает действительное ненулевое целое число.

Преобразования Integer-to-bool определяются командой [conv.bool]:

Значение нуля, значение нулевого указателя или значение указателя нулевого элемента преобразуется в значение false; любое другое значение преобразуется в true

поэтому bool t2 = ~t; дает t2 == true. Не существует поведения undefined.


~f совпадает с ~0. В 2 дополнениях ~0 дает -1, поэтому мы будем иметь f2 == true.

В 1 дополнение - если была когда-либо система С++, которая использует 1 дополнение, то эффект ~0 неясен.

Ответ 3

bool t = true;
bool t2 = ~t;    // is t2 guaranteed to be false, or is this UB?

Я полагаю, что это не гарантируется, видя, как

  bool b = true;
  bool b1 = ~b;
  cout << b1;

выводит "true"

Я полагаю, что это связано с булевым представлением... если это байт, то 00000001 будет отрицать значение 11111110, которое не равно нулю. Продвижение может также играть, но это та же мелодия.

Ключевым моментом здесь является "поразрядное" не "логическое". Поэтому не следует ожидать, что они совпадают, если только логическое представление не является единственным.

Легко полностью определенное поведение.