Почему операция сдвига влево вызывает неопределенное поведение, когда левый операнд имеет отрицательное значение?
В 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 и почему оператор правого сдвига вызывает только поведение, определенное реализацией?
П.С .: Пожалуйста, не давайте ответов типа «Это неопределенное поведение, потому что стандарт так говорит». :П