Страницы

Поиск по вопросам

среда, 1 января 2020 г.

При каких условиях в C битовый сдвиг влево для знакового целого приводит к неопределенному поведению?

#c #неопределенное_поведение


Ясное дело, что << и >> не должны принимать справа отрицательное число, но дальше
я ничего не понял.
    


Ответы

Ответ 1



Если под "сдвигом для знакового целого" подразумевается сдвиг, в котором "знаковым целым" является левый операнд, то стоит помнить, что левый операнд сдвига подвергается integer promotions. То есть даже если в выражении a << b значение a является знаковым, на некоторых экзотических платформах оно может стать беззнаковым после integer promotions. Поэтому далее будем рассматривать выражение a << b, где a - значение после integer promotions и оно по-прежнему знаковое. Битовый сдвиг влево a << b для знакового целого a приводит к неопределенному поведению когда b < 0 Значение b превосходит битовую ширину a или равно ей a < 0 При сдвиге произошло переполнение, т.е. значение a*2b (вычисленное математически верно) не помещается в диапазон типа a Первые два пункта относятся ко всем сдвигам. Выражаясь более приземленным языком, последние два пункта говорят, что нельзя двигать влево единицу в знаковом бите и нельзя вдвигать справа единицу в знаковый бит.

Ответ 2



Вот что пишет стандарт: Значение результата операции E1 << E2 есть значение E1, сдвинутое влево на E2 битовых позиций; биты, остающиеся свободными, заполняются нулями. Если тип E1 беззнаковый, то значение результата есть E1×2E2, взятое по модулю, на единицу большему, чем максимальное значение, представимое результирующим типом. В противном случае, если E1 имеет знаковый тип и неотрицательное значение, а значение E1×2E2 представимо в соответствующем результирующему типу беззнаковом типе, то это значение, преобразованное к результирующему типу, и служит результирующим значением; в противном случае поведение программы не определено. Так понятнее? :)

Комментариев нет:

Отправить комментарий