Присвоение максимального значения меньшего целого числа большему целому числу - PullRequest
2 голосов
/ 02 ноября 2010

Рассмотрим следующий код:

 uint32_t x = ~uint8_t(0);
 std::cout << x << std::endl;

Теперь я полностью ожидал, что это выдаст 255, но вместо этого он выдаст 4294967295.

Мне известно о целочисленном продвижении в C ++, но я не могу понять, почему это произошло. Насколько я понимаю, выражение ~uint8_t(0) должно оцениваться до 1111 1111 в двоичном виде. Оператор ~ будет приводить к тому, что тип будет повышен до int (для обсуждения я буду считать его 32-битным), при этом знак расширяет значение до 0000 0000 0000 0000 0000 0000 1111 1111. Это повышенное значение должно быть присвоено lvalue x, в результате чего x == 255.

Но, очевидно, я не правильно понимаю это. Чего мне не хватает?

Ответы [ 2 ]

7 голосов
/ 02 ноября 2010

Интегральные продвижения выполняются на операнде унарного ~, поэтому uint8_t(0) повышается до int, а затем оценивается ~.Это эквивалентно

~(int)(uint8_t)0

. Вы можете получить максимальное значение, представляемое типом, используя std::numeric_limits<T>::max();если тип без знака, вы также можете привести -1 к этому типу:

uint32_t x = (uint8_t)-1;
2 голосов
/ 02 ноября 2010

В вашем примере, побитовый оператор not (~) переводит свой операнд в int перед выполнением. Затем он преобразуется в unsigned int по присваиванию.

Вот несколько примеров кода, которые проясняют это:

uint8_t y = ~uint8_t(0);
uint32_t x = y;
std::cout << x << std::endl;

255

uint8_t y = uint8_t(0);
int z = ~y;
uint32_t x = z;
std::cout << x << std::endl;

4294967295

...