Почему операция сдвига влево вызывает неопределенное поведение, когда левый операнд имеет отрицательное значение?

В C операция побитового сдвига влево вызывает неопределенное поведение, когда левый боковой операнд имеет отрицательное значение.

Соответствующая цитата из ISO C99 (6.5.7 / 4)

Результатом E1 << E2 является E1 сдвинутая влево битовая позиция E2; освобожденные биты заполняются нулями. Если E1 имеет тип без знака, значение результата будет E1 × 2E2, уменьшено по модулю на единицу больше максимального значения, представляемого в типе результата. Если E1 имеет тип со знаком и неотрицательное значение, а E1 × 2E2 представимо в типе результата, то есть полученное значение; иначе,поведение не определено.

Но в C ++ поведение четко определено.

ISO C ++ - 03 (5.8 / 2)

Значение E1 << E2 - это E1 (интерпретируется как битовая комбинация) смещенных влево битовых позиций E2; освобожденные биты заполнены нулями. Если E1 имеет тип без знака, значение результата равно E1, умноженному на величину 2, возведенную в степень E2, по модулю ULONG_MAX + 1, если E1 имеет тип unsigned long, в противном случае UINT_MAX + 1. [Примечание: константы ULONG_MAX и UINT_MAX определены в заголовке). ]

Это означает

int a = -1, b=2, c;
c= a << b ;

вызывает неопределенное поведение в C, но поведение хорошо определено в C ++.

Что заставило комитет ISO C ++ считать, что поведение четко определено, а не поведение в C?

С другой стороны, поведениеimplementation defined для операции побитового сдвига вправо, когда левый операнд отрицательный, верно?

Мой вопрос: почему операция левого сдвига вызывает неопределенное поведение в C и почему оператор правого сдвига вызывает только поведение, определенное реализацией?

П.С .: Пожалуйста, не давайте ответов типа «Это неопределенное поведение, потому что стандарт так говорит». :П

Ответы на вопрос(8)

Ваш ответ на вопрос