Bitshift и целочисленное продвижение? - PullRequest
27 голосов
/ 14 августа 2010

Обычно C требует, чтобы операнды бинарного оператора были переведены в тип операнда более высокого ранга. Это можно использовать, чтобы избежать заполнения кода подробными приведениями, например:

if (x-48U<10) ...
y = x+0ULL << 40;

и т.д.

Однако я обнаружил, что, по крайней мере с gcc, это поведение не работает для битовых сдвигов. * Т.е. 1006 *

int x = 1;
unsigned long long y = x << 32ULL;

Я ожидаю, что тип правого операнда вызовет повышение левого операнда до unsigned long long, чтобы сдвиг завершился успешно. Но вместо этого gcc выдает предупреждение:

warning: left shift count >= width of type

Не нарушен ли gcc или стандарт делает какое-то исключение из правил продвижения типов для битовых сдвигов?

Ответы [ 2 ]

30 голосов
/ 14 августа 2010

Так называемые обычные арифметические преобразования применяются ко многим бинарным операторам, но не ко всем.Например, они не применяются к операторам сдвига битов, &&, ||, операторам запятой и операторам присваивания.Это правило для операторов сдвига битов:

6.5.7 ... 3 Семантика ...
Целочисленные преобразования выполняются для каждого из операндов.Тип результата - тип повышенного левого операнда.Если значение правого операнда отрицательно или больше или равно ширине повышенного левого операнда, поведение не определено.

0 голосов
/ 08 января 2014

Проблема в том, что продвижение работает только в соответствии с тем, что ваша платформа определяет как int. Как уже говорилось в некоторых других ответах, оператор сдвига бит переводит левый операнд в int. Однако здесь int определяется как 32-битное значение. Целочисленное преобразование не будет преобразовано в long long (64-разрядное).

...