ограниченный диапазон типов данных - PullRequest
0 голосов
/ 02 апреля 2019

Когда я компилирую этот фрагмент кода в GCC:

uint8_t *reg = ..., newflags = ...;
...
if(*reg == (~(uint8_t)0))
{
    newflags |= (1<<2);
    newflags |= (1<<7);
}

я получаю это предупреждение: warning: comparison is always false due to limited range of data type [-Wtype-limits]

reg и newflags равны uint8_t * и uint8_t типы, соответственно.

Что это значит?И что мне сделать, чтобы это исправить?

1 Ответ

5 голосов
/ 02 апреля 2019

~(uint8_t)0 должно быть (uint8_t)~0. Операнд в ~, как и в других арифметических операторах, будет расширен до int (или до unsigned int, если не все значения исходного типа представимы в int) и int 0 со всеми инвертированными битами выходит за пределы диапазона uint8_t, за исключением случаев, когда реализация поддерживает отрицательные нули ... Цитирование предыдущей версии священной книги , 6.5.3.3p4

  1. Результатом оператора ~ является побитовое дополнение его (повышенного) операнда (то есть каждый бит в результате устанавливается, если и только если соответствующий бит в преобразованном операнде не установлен) , Целочисленные преобразования выполняются для операнда, и результат имеет продвинутый тип. Если продвигаемый тип является типом без знака, выражение ~E эквивалентно максимальному значению, представляемому в этом типе, минус E.

Для максимальной совместимости вы должны использовать 0U вместо 0, чтобы обеспечить повышение значения до unsigned int вместо int, но весьма вероятно, что ваш компьютер является дополнением до 2, особенно с типы фиксированной ширины, такие как uint8_t - и поведение (uint8_t)~0 будет эквивалентно (uint8_t)~0U (может отличаться от дополнения 1 или знака и величины!).

...