Не имеет большого значения, что означают эти строки, они по существу неверны.
"Если значение после оператора сдвига
больше, чем количество бит в
левый операнд, результат
не определено. "
Верно, но должно сказать "больше или равно". 5,8 / 1:
... поведение не определено, если
правый операнд отрицательный, или
больше или равно длине в
биты повышенного левого операнда.
Неопределенное поведение означает «не делай этого» (см. Позже). То есть, если int
- это 32 бита в вашей системе, вы не можете выполнить одно из следующих действий:
int a = 0; // this is OK
a >> 32; // undefined behavior
a >> -1; // UB
a << 32; // UB
a = (0 << 32); // Either UB, or possibly an ill-formed program. I'm not sure.
"Если левый операнд не подписан, правый сдвиг является логическим сдвигом, поэтому старшие биты будут заполнены нулями."
Это правда. 5.8 / 3 говорит:
Если E1 имеет тип без знака или E1 имеет
тип со знаком и неотрицательное значение,
результат является неотъемлемой частью
отношение E1, деленное на количество
2 возведены в степень Е2
если это имеет больше смысла для вас. >>1
- это то же самое, что деление на 2, >>2
деление на 4, >>3
на 8 и так далее. В двоичном представлении положительного значения деление на 2 - это то же самое, что перемещение всех битов на один вправо, отбрасывание наименьшего бита и заполнение самого большого бита 0.
"Если левый операнд подписан, правый сдвиг может быть или не быть логическим сдвигом (то есть поведение не определено)."
Первая часть верна (это может быть или не быть логическим сдвигом - это на некоторых компиляторах / платформах, но не на других. Я думаю, что наиболее распространенным поведением является то, что это не так). Вторая часть неверна, поведение не определено. Неопределенное поведение означает, что разрешено все, что угодно - авария, демоны вылетающие из носа, случайное значение, что угодно. Стандарту все равно. Есть много случаев, когда стандарт C ++ говорит, что поведение не определено, но это не один из них.
Фактически, если левый операнд подписан, а значение положительное, то он ведет себя так же, как и беззнаковое смещение.
Если левый операнд подписан, а значение отрицательное, то результирующее значение определяется реализацией. Не допускается падение или загорание. Реализация должна давать результат, а документация для реализации должна содержать достаточно информации, чтобы определить, каким будет результат. На практике «документация для реализации» начинается с документации компилятора, но она может явно или неявно ссылаться на другие документы для ОС и / или ЦП.
Опять из стандарта, 5,8 / 3:
Если E1
имеет тип со знаком и отрицательный
значение, полученное значение
реализации.