> Does it mean "If E1 has negative value, or E1 × 2*E2 is unrepresentable, then the behavior is undefined"? Because that's a ridiculous ordinance.
That's exactly what it means, see the change mentioned in https://www.open-std.org/jtc1/sc22/wg14/www/docs/n723.htm. (Previously, in C89, left shift on signed integers was completely undefined, only unsigned integers had a defined left-shift operation.) My guess is that it has to do with signed-magnitude representation causing left shifts to be absolute garbage with negative numbers. You also have to remember that the standard having undefined behavior doesn't preclude implementations from defining that behavior, and this is especially true with the freewheeling nature of a lot of the original undefined behavior introduced in C89 and C99.
> Also, C23 (and C2y) is moving ever closer to actually having defined semantics.
Eh, having seen how some of the sausage gets made, there's definitely been some cases where the overeager urge to rip out undefined behavior from the standard has worsened the quality.
> My guess is that it has to do with signed-magnitude representation causing left shifts to be absolute garbage with negative numbers.
First of all, why not make it implementation-defined? That seems rather more useful for the programmer. Second, I'm personally aware of only a single machine with signed-magnitude representation, IBM 7090, and its ALS (Accumulator Left Shift) instruction treated the sign bit as sticky; amusingly, LGL (Logical Shift Left) did as well, so you had to put the value being shifted into the MQ register, not the accumulator, when you wanted an unsigned shift. So... no, that can't be it?
Well, you could start to help? (instead of just being there to make sure special interests are preserved in voting)
I also do not see where the quality suffered. There were some rather minor issues we created and need to cleaned up.