Почему битовая операция на целочисленных типах, меньших 4 байтов, ведет себя неожиданно? - PullRequest
0 голосов
/ 10 мая 2018

Пожалуйста, рассмотрите пример кода, где я хочу проверить, установлены ли все биты в целочисленной переменной без знака.IntegerType заменяется на uint8_t, uint16_t, uint32_t uint64_t.

Вопрос: почему утверждение успешно для IntegerType = uint32_t и uint64_t, хотя оно не выполняется для uint16_t и uint8_t?

#include <cstdint>
#include <cassert>

IntegerType bitset = -1; // set all bits to true

IntegerType t = ~bitset;
bool bAllBitsSet1 = (t == 0);
bool bAllBitsSet2 = ((~bitset) == 0);

assert(bAllBitsSet1 == bAllBitsSet2);

1 Ответ

0 голосов
/ 10 мая 2018

Это происходит из-за целочисленного продвижения: первое выражение приводит ~bitset обратно к более короткому типу, в то время как второе выражение использует полное целочисленное значение.

Для целочисленных типов короче int значение повышается до int перед выполнением операции, в данном случае, перед применением к ней ~.

Рассмотрим uint16_t для примера. Когда вы пишете

uint16_t t = ~bitset;

значение bitset повышается до int, поэтому оно становится 0x0000FFFF на 32-битной платформе. Затем ~ применяется, производя 0xFFFF0000. Наконец, результат записывается обратно в t, отсекая старшие биты. Следовательно, t равно нулю.

С другой стороны, когда вы сравниваете ~bitset напрямую с нулем, сравнение не выполняется, потому что 0xFFFF0000 не равно нулю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...