эта, почему int x >> 32 == x?
А сделай еще на 33 и 64. Что будет? Просто любопытно.
А сделай еще на 33 и 64. Что будет? Просто любопытно.У меня 33-40 получилось как 1-8. Может быть какая оптимизация в процессоре или даже фича, что смещение делается не на i, а на i & 31?
Если налево двигать, то такая же фигня.
Не знаю, как в C/C++, но в Java (x >> y) эквивалентно (x >> (y & 31 если x типа int и (x >> (y & 63 если x типа long. То есть учитываются только 5 (6 для long) младших бит второго аргумента.
Welcome to C and undefined behavior. Некоторые процессоры, в том числе x86, обрезают величину сдвига до логарифма размера слова в битах.
Welcome to C and undefined behavior. Некоторые процессоры, в том числе x86, обрезают величину сдвига до логарифма размера слова в битах.Так причём здесь C? Вон даже в Java как фичу объявили.
Это процессор же так делает. Мы тут сейчас как минимум на AMD, Intel X86 и на каком-то Sun проверили.
и в ассемблерном листинге не видно хаков, это проц самолично
В Java такой результат гарантируется (на любых процессорах, даже тех, которые сами не обрезают а в Си может быть что угодно. Может даже диск отформатироваться.
Welcome to C and undefined behavior. Некоторые процессоры, в том числе x86, обрезают величину сдвига до логарифма размера слова в битах.угу, причём так было не всегда. насколько я помню i386 двигал всё а 486 начал обрезать
В Java такой результат гарантируется (на любых процессорах, даже тех, которые сами не обрезаютНу если у жабы такое в спецификации, то наверняка большинство процессоров так делает.
У кого-нибудь на ARM-ах каких-нибудь компилятор есть? Тоже было бы интересно как там.
Ну если у жабы такое в спецификации, то наверняка большинство процессоров так делает.Армы обрезают до восьми бит, а не до пяти.
У кого-нибудь на ARM-ах каких-нибудь компилятор есть? Тоже было бы интересно как там.
Армы обрезают до восьми бит, а не до пяти.Интересно. Ну X86 тоже не обязательно до 5 бит обрезает. У меня для лонга до 6 обрезало.
:собака-подозревака:Ну если у жабы такое в спецификации, то наверняка большинство процессоров так делает.Армы обрезают до восьми бит, а не до пяти.
У кого-нибудь на ARM-ах каких-нибудь компилятор есть? Тоже было бы интересно как там.
Если речь не про какой-нибудь arm64 (и уж тем более thumb а про 32-битный arm, то вообще-то до пяти, при этом для обсуждаемого lsr допустимые значения от 1 до 32 включительно. Иначе, прошу привести пример машинного кода инструкции "lsr r0, r0, #33".
речь про случаи когда величина сдвига в регистре
Да, тогда нет возражений, всё верно.
Welcome to C and undefined behavior. Некоторые процессоры, в том числе x86, обрезают величину сдвига до логарифма размера слова в битах.
Я бы хотел заметить, что ты вносишь сумятицу в наивные мозги людей, как бы приравнивая undefined behaviour к unspecified behaviour.
Вношу ясность, подключаемся, работаем: в языках C и C++ всё поведение чотко определено, и есть три разных понятия:
1. implementation-defined behaviour: например, 4 == sizeof(int). Твой компилятор для твоей таргет платформы обязан определить это поведение и делать всегда так. Если твоя программа работает ОК с этим компилятором для этой платформы, она так и будет работать, но может перестать работать с другим компилятором/на другой платформе.
2. unspecified behaviour: например, порядок вычисления параметров функции. f(g h: если g и h делают какие-то глобально-видимые вещи, порядок деланья этих вещей может меняться между двумя последовательномыми вызовами "f(g h", и меняться ещё раз между разными компиляциями тем же самым компилятором, и вообще. Если порядок для тебя важен, то это баг в твоей программе. Читай про sequence points в стандарте.
3. undefined behaviour: например, integer overflow (also, overflowing shifts): ты может не знаешь, но ты подписался что ты никогда не будешь этого делать. Так что компилятор может фигачить код который работает правильно если undefined behaviour не происходит, и делает неведомую хуйню если он происходит. И даже тупо выкидывать код который триггерит undefined behaviour, например, if (x + y < x) любой вменяемый компилятор будет считать always false, и генерить код соответственно. Если тебе кажется что то, что ты компилишь под x86 где integer overflow будет вот так проявляться, тебе кажется неправильно, компилятор тупо выкинет эту проверку.
хм, оно больше на undefined похоже. если сдвиг константный и вычислился при компиляции то 1<<32 gcc превращает в ноль (попутно кидая ворнинг) а если не константный то будет 1.
undershift (есть такой термин вообще?) знакового типа - implementation defined.
Оставить комментарий
yolki
*джекичанwhy?*