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

В 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

41
задан Deduplicator 3 July 2015 в 16:28
поделиться