Каков результат a & b?
Это неудобно, но побитовый оператор AND определен в стандарте С++ следующим образом (выделение мое).
Выполняются обычные арифметические преобразования; результатом является побитовая функция И его операндов. Оператор применяется только к интегральным или неперечисленным операндам перечисления.
Это выглядит для меня бессмысленным. Насколько я могу видеть, "побитовая функция И" не определена нигде в стандарте.
Я понимаю, что функция И хорошо понятна и, следовательно, может не потребовать объяснений. Значение слова "побитовое" также должно быть довольно ясным: эта функция применяется к соответствующим битам ее операндов. Однако то, что составляет биты операндов, не ясно.
Что дает?
Ответы
Ответ 1
Это недоказано. Вопрос о том, что означает стандарт, когда он относится к побитовым операциям, является предметом нескольких отчетов о дефектах.
Например отчет о дефектах 1857: Дополнительные вопросы о битах:
Спецификация побитовых операций в 5.11 [expr.bit.and], 5.12 [expr.xor] и 5.13 [expr.or] использует термин undefined "поразрядный" при описании операций, не указывая, является ли это представление значения или объекта, которое находится в поле зрения.
Частью разрешения этого может быть определение "бит" (который иначе в настоящее время undefined в С++) в качестве значения заданной мощности 2.
и ответ был:
CWG решила переформулировать описание операций сами избегать ссылок на биты, отделяя больше вопросы определения "бит" и т.п. для выпуска 1943 года для дальнейшего рассмотрение.
и отчет о дефекте 1943 гласит:
CWG приняла решение на собрании 2014-06 (Rapperswil) для решения только ограниченное подмножество вопросов, поднятых по вопросам 1857 и 1861. Это вопрос является заполнителем для оставшихся вопросов, таких как определение "бит" в терминах значения 2 n указав, имеет ли бит-поле знаковый бит и т.д.
Мы можем видеть из этого отчета отчет о дефектах 1796: Является ли all-bits-zero для нулевых символов значимым требованием?, эта проблема что означает стандарт, когда он относится к битам, затронутым и затрагивающим другие разделы:
Согласно пункту 2.3 [lex.charset],
Основной набор символов выполнения и набор символов широкого исполнения должны содержать все элементы основного исходный набор символов, плюс управляющие символы, представляющие предупреждение, backspace и возврат каретки плюс нулевой символ (соответственно, null широкий символ), представление которого имеет все нулевые биты.
Не ясно, что переносная программа может проверять биты представление; вместо этого он, по-видимому, будет ограничен изучением биты чисел, соответствующие представлению значения (3.9.1 [basic.fundamental] пункт 1). Это может быть более уместным потребовать, чтобы значение нулевого символа сравнивалось с 0 или '\ 0' вместо указания битовой диаграммы представления.
Существует аналогичная проблема для определения сдвига, побитового и, и побитовые или операторы: являются ли эти спецификации ограничениями на бит образ представления или значения, полученные в результате интерпретация этих моделей как чисел?
В этом случае разрешение должно было измениться:
имеет все нулевые биты
в
значение равно 0.
Обратите внимание, что как указано в ответе ecatmur, проект стандарта С++ откладывает до стандартного раздела C 5.2.4.2.1
в разделе 3.9.1
[basic.fundamental] в параграфе 3
он не относится к разделу 6.5/4
из стандарта C, который, по крайней мере, говорит нам, что результаты определены реализацией. Я объясняю в своем комментарии ниже, что стандарт С++ может включать только текст из нормативных ссылок явно.
Ответ 2
[basic.fundamental]/3 отсылает к C 5.2.4.2.1. Кажется разумным, что побитовые операторы в С++, будучи underspecified, должны аналогичным образом относиться к C, в этом случае 6.5.10/4:
Результатом двоичного и оператора является побитовое И из операндов (т.е. каждый бит в результат устанавливается тогда и только тогда, когда каждый из соответствующих битов в преобразованных операндах установлен).
Обратите внимание, что C 6.5/4 имеет:
Некоторые операторы (унарный оператор ~
и бинарные операторы <<
, >>
, &
, ^
и |
, совместно описываемые как побитовые операторы), должны иметь операнды, которые имеют целочисленный тип. Эти операторы дают значения, зависящие от внутренних представлений целые числа и имеют определенные для реализации и undefined аспекты для подписанных типов.
Внутренние представления целых чисел, конечно, описаны в 6.2.6.2/1,/2.
Ответ 3
Стандарт С++ определяет хранилище как определенное количество бит. Реализация может решить, какой смысл приписывать конкретный бит; что, как сказано, двоичный И должен работать над концептуальными 0s и 1s, образующими конкретное представление типа.
3.9.1.7. (...) Представления интегральных типов должны определять значения с использованием чистой двоичной системы нумерации. 49 (...)
3.9.1, сноска 49) Позиционное представление для целых чисел, которое использует двоичные цифры 0 и 1, в которых значения, представленные последовательными биты являются аддитивными, начинаются с 1 и умножаются на последовательную интегральную мощность 2, за исключением, возможно, для бит с наивысшим Положение
Это означает, что для любого используемого физического представления двоичный И действует в соответствии с таблицей истинности для функции И (для каждого номера бит я беру биты A i и B i из соответствующих операндов и выдает значение 1, только если оба они равны 1, в противном случае производят 0 для бит R i). Результирующее значение остается интерпретировать реализацией, но все, что выбрано, он должен соответствовать другим ожиданиям в отношении других двоичных операций, таких как OR и XOR.
Ответ 4
С юридической точки зрения мы могли бы считать, что все побитовые операции имеют поведение undefined, поскольку они фактически не определены.
Более разумно, мы должны применять здравый смысл и ссылаться на общие значения этих операций, применяя их к битам операндов (отсюда и термин "поразрядный" ).
Но об этом ничего не говорится. Позор мой ответ не может считаться нормативной формулировкой.