В C операция побитового сдвига влево вызывает Undefined Behavior, когда левый операнд имеет отрицательное значение.
Соответствующая цитата из ISO C99 (6.5.7 / 4)
Результат E1 << E2 - E1 сдвинутые влево позиции битов E2; освобожденные биты заполняются нулями. Если E1 имеет беззнаковый тип, значение результата будет E1 × 2 E2 , уменьшенное по модулю на единицу больше, чем максимальное значение, представленное в типе результата. Если E1 имеет подписанный тип и неотрицательное значение, и E1 × 2 E2 может быть представлен в типе результата, то это полученное значение; в противном случае поведение не определено .
Но в 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 ;
вызывает Undefined Behavior в C, но поведение хорошо определено в C ++.
Что заставило комитет ISO C ++ считать это поведение хорошо определенным, в отличие от поведения в C?
On с другой стороны, поведение реализация, определенная
для операции побитового сдвига вправо, когда левый операнд отрицательный, вправо?
Мой вопрос: почему операция сдвига влево вызывает неопределенное поведение в C и почему оператор сдвига вправо вызывать только поведение, определяемое реализацией?
PS: Пожалуйста, не давайте ответов типа «Это неопределенное поведение, потому что так сказано в Стандарте». : P