Интригующее поведение оператора правого сдвига
Оператор правого сдвига (>>) демонстрирует необычное поведение при работе с большими значениями сдвига вправо. Рассмотрим следующую программу:
#include
#include
int foo(int a, int b)
{
return a >> b;
}
int bar(uint64_t a, int b)
{
return a >> b;
}
int main()
{
std::cout > 32: " > 32) > (int)32: " > (int)32) Ожидаемый результат для foo(1, 32) будет 0, но, что удивительно, он возвращает 1. Это можно объяснить следующим:
Логический сдвиг против арифметического Shift
В архитектурах x86/x86-64 оператор сдвига вправо фактически выполняет логический сдвиг вправо, что означает, что он заполняет освободившиеся биты 0, независимо от знак левого операнда. Поведение аналогично использованию >>> b.
Оптимизация компилятора
В случае foo(1, 32) значение 32 преобразуется в int, который фактически усекается до 32 бит. Поскольку максимальное значение, которое может содержать int, равно 231-1, правый сдвиг по существу представляет собой >>> (32 % 32), который оценивается как 0.
Undefined Поведение
Соответствующий стандарт C гласит, что «поведение не определено» для сдвигов вправо со счетом, большим или равным ширине повышенного левого операнда. В этом случае и 1 >> 32, и (int)1 >> (int)32 имеют счетчик больше 32, что приводит к непредсказуемым результатам.
Разница с bar(1, 32)
Функциональная панель принимает 64-битное целое число без знака, ширина которого гарантированно превышает 32. Таким образом, неопределенное поведение не влияет на сдвиг вправо в строке.
Заключение
Поведение оператора правого сдвига становится неоднозначным при работе с большими значениями сдвига. На архитектурах x86/x86-64 выполняется логический сдвиг вправо, а на ARM может использоваться другая реализация. Из-за неопределенного поведения в переносимом коде следует избегать результатов сдвигов вправо со счетчиком, превышающим или равным ширине операнда.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3