Почему сдвиг на полную ширину ведет себя по-разному для постоянной и переменной? - PullRequest
0 голосов
/ 08 февраля 2019

Если я использую 3 << 32, я получаю правильный результат.Если я найду размер с помощью sizeof(int), умножу на 8, сохраню результат в переменной, а затем использую 3 << variable, я получу другой результат.Что мне здесь не хватает?

void func()
{
    unsigned int sz = sizeof(number) * 8;
    unsigned int k = 0;
    printf("Value of sz is %u \r\n",sz);
    k = (k | (0x3) << sz);
    printf("Value of 2_1_MSB is %d \r\n",(3 << 32));
     printf("Value of k is %u \r\n",k);
}

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

На всех современных платформах типа ПК int имеет только 32 бита.Сдвиг больше, чем это не определено.И помните, что битовые числа для сдвига начинаются с нуля, поэтому для 32-битного типа (например, int) допустимый диапазон битов составляет от 0 до 31 (включительно).

Теперь дляразница между 3 << 32 и 3 << sz: в первом случае компилятор может знать, что он смещается более чем на 32 бита, поэтому он может заключить, что это будет 64-разрядная операция (с использованием long long).Во втором случае компилятор не знает значение sz, потому что это простая переменная, а не константа времени компиляции.Следовательно, он должен предполагать, что это простой int сдвиг и что значение sz находится в диапазоне.

0 голосов
/ 08 февраля 2019

Стандарт C определяет поведение сдвига только для сдвигов, меньших ширины смещаемого типа (C 2018 6.5.7 3).Смещение 32-битного int на 32 бита не определено стандартом.

Различия между 3 << 32 и (0x3) << sz могут возникнуть из-за того, что компилятор оценивает первое во время компиляции (возможно, с использованием операциикоторый сдвигает все биты, что приводит к нулю), а последний - во время выполнения (возможно, с использованием инструкции, которая использует только младшие пять битов величины сдвига, что не приводит к сдвигу).На такое поведение нельзя полагаться;они могут изменяться при оптимизации, изменении цели или другой конфигурации компилятора, изменении версии компилятора и т. д.

...