Когда переменная или значение меньше, чем 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; }