Предупреждение двоичного оператора c ++

3

c++,binary,bitwise-operators,

C ++, бинарные, битовые-операторы,

Ответов: 2


3

Когда переменная или значение меньше, чем 0xffffffffучаствует в арифметическом выражении, оно неявно преобразуется в an int. Для некоторых типов компилятор может выполнить другое неявное преобразование обратно к исходному типу, но в других это невозможно без потери данных.

Возьмем, например, ваше значение без знака 0xffffffff. При преобразовании в a intоно становится -1. Побитовое дополнение превращает его в int, которое не может быть преобразовано обратно в беззнаковый байт без потери данных.

И это особенно плохо для таких ценностей, потому что, поскольку intзначение unsigned intравно (читайте о дополнении 2, чтобы узнать, почему), который не может быть действительно преобразован в unsigned byte чисто.int main() { uint8_t a = 0x00U; uint8_t b = 0x01U; a = a | b; a |= b; a = static_cast<uint8_t>(~b); a = a | static_cast<uint8_t>(~b); a |= static_cast<uint8_t>(~b); return 0; }

Поэтому, а также не подвергать риску переполнение (если это не требуется), я предлагаю вам выполнить всю целочисленную арифметику с использованием int(или ). Затем не конвертируйте их в более мелкие типы, пока они вам не понадобятся.int main() { uint32_t a = 0x00U; uint32_t b = 0x01U; a = a | b; a |= b; a = ~b; a = a | ~b; a |= ~b; return 0; }


0

Вот две возможности, если вы не хотите никаких предупреждений:

Решение 1:

operator ~

Решение 2:

uint32_t value = 0xFFFFFFFF;
uint32_t mask = 0xFFu;

value &= mask; // Now value is 0x000000FF

Вы могли бы подумать, что второй менее эффективен, потому что он использует большие числа, это на самом деле неверно. В первом решении неявные преобразования в 32-разрядные числа из-за стоимости некоторой памяти и производительности. Второе решение должно быть более эффективным. В общем, вы должны использовать (по крайней мере) uint32_t и использовать маски, если хотите 8-битное значение:a = a | b; // no warning a |= b; // no warning

|

0

Компилятор умный: uint8_t a = 0x00U; uint8_t b = 0x01U;

a|b

учитывая два 8-битных значения, intне может установить бит выше 8. Таким образом, никакие биты не теряются при преобразовании обратно в 8 бит.

Результат ~a- intнезависимо, но компилятор также знает, что это 8-битный чистый int.

Результат aявляется не 8 - битным чистым Int - aпреобразуется в (возможно , 32 битах) Int, то все биты инвертируются (установка старших бит). Поэтому, если преобразованные обратно в 8 бит, некоторые бит старшего порядка теряются.

Это верно во всех этих случаях:

a = ~b;     // warning
a = a | ~b; // warning
a |= ~b;    // warning

после a=~b, a==~bне соответствует действительности. В a=a|~bслучае, если мы сохранили результат auto c=a|~b;, то сделал a=c, a==cне было бы правдой впоследствии. |=Случай имеет аналогичное замечание осложненных самомодификаций.

C ++, бинарные, битовые-операторы,
Похожие вопросы
Яндекс.Метрика