Зависят ли операторы левого смещения от размера регистра? - PullRequest
1 голос
/ 23 июня 2019

Пусть uint8 и uint16 будут типами данных для 8-битных и 16-битных натуральных чисел.

uint8 a = 1;
uint16 b = a << 8;

Я тестировал эту программу на 32-битной архитектуре с результатом

b = 256

Будет ли та же самая программа в системе с регистрами 8-битной длины давать результат:

b = 0?

потому что все биты в регистре сдвигаются в 0 на << 8? </p>

Ответы [ 2 ]

3 голосов
/ 23 июня 2019

Регистры не имеют значения.Это примерно ширина ваших типов.

Когда вы сдвигаете значение на большее количество бит, чем оно имеет, поведение не определено.Компилятор, программа, компьютер, налоговая инспекция могут юридически проявить любые результаты соответственно.И, нет, это не просто теоретический .

Тем не менее, операнды в C * повышаются до того, как на них сделаны интересные вещи .Итак, ваш uint8_t становится int до сдвига влево.

Теперь это зависит от вашей архитектуры (как определено конфигурацией вашего компилятора) относительно того, что происходит: is int на твоей реализации только 8-битный? Нет, это не так! В результате, независимо от какого-либо "размера регистра", результат должен соответствовать правилам языка, давая математически подходящий ответ (256). И,даже если бы это было так, вы бы столкнулись с этим неопределенным поведением, поэтому вопрос был бы спорным.

Под капотом, если для хранения переменной требуется более одного регистра, то это то, что будет и должно произойти (прикакие бы эксплуатационные расходы не подразумевались в результате).Это если регистр используется вообще ;помните, вы программируете в абстракции, а не в машинном коде ручной работы.Показанный вами фрагмент программы может быть полностью оптимизирован во время компиляции и не требует никаких инструкций во время выполнения вообще .

2 голосов
/ 23 июня 2019

Будет ли эта же программа в системе с регистрами длиной 8 бит иметь результат b=0?

номер

В выражении a << 8 переменная a получит повышенное до int до сдвига битов. И int гарантированно будет по крайней мере 16 бит.

b будет иметь значение 256 на всех платформах, если в компиляторе нет ошибки.

Однако, если вы изменили вторую строку на uint32 b = a << 16;, вы можете получить странные результаты. a все равно будет преобразован в int, но если int имеет длину в два байта, то a << 16 вызовет неопределенное поведение.

...