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