Сдвиг вправо ›› в C99


person osgx    schedule 13.04.2011    source источник


Ответы (1)


Сдвиг 32-битного целого числа на 32 бита является неопределенным поведением. Результат не предсказуем.

В C и C++, если целое число имеет N бит, вам разрешено смещаться только менее чем на N бит. Если вы сдвинете N или более, поведение не будет определено.

На практике при сдвиге 32-битного целого числа некоторые платформы просто интерпретируют счетчик сдвигов как 5-битное значение (отбрасывая любые биты выше младших 5), что означает, что 32 будет интерпретироваться так же, как 0. Это, по-видимому, то, что происходит на вашей платформе. Значение вообще не смещается.

person AnT    schedule 13.04.2011
comment
Но что в этом случае делают основные компиляторы? - person osgx; 13.04.2011
comment
@osgx: они делают все, что хотят, поведение не определено. - person Tony The Lion; 13.04.2011
comment
@osgx: компилятор, скорее всего, просто сгенерирует простую инструкцию сдвига для ЦП и забудет о ней. Таким образом, поведение будет определяться поведением инструкции сдвига процессора. В вашем случае он просто проигнорировал сдвиг. - person AnT; 13.04.2011
comment
@osgx, я подозреваю, что компилятор берет правую часть оператора сдвига по модулю 32. Так что в этом случае i >> 32 становится i >> (32 % 32) == i >> 0 == i. - person JSBձոգչ; 13.04.2011
comment
@AndreyT, вероятно, прав, на самом деле моддингом занимается процессор, а не компилятор. - person JSBձոգչ; 13.04.2011
comment
@osgx: почему это важно? Если вы полагаетесь на поведение основных компиляторов, когда оно не определено, ваш код ужасно сломан. - person Wooble; 13.04.2011
comment
@Wooble: я полностью согласен, но мне интересно, согласитесь ли вы с вашей собственной логикой, примененной к (-1)<<1, которая также имеет неопределенное поведение. - person R.. GitHub STOP HELPING ICE; 13.04.2011
comment
@R..: Стандарты C не требуют, чтобы реализации указывали какое-либо конкретное поведение при переполнении чисел со знаком, но позволяют им это делать. Если в реализации указано, что подписанное переполнение приведет к определенному поведению, подписанное переполнение не вызовет Undefined Behavior на этой платформе. - person supercat; 20.11.2013