Jordan said:
Then what could cause the left-hand operand (being, as established,
unsigned char) to be promoted to int at all? Is there some magical "all
types narrower than int get promed to int all the time no matter what"
rule i haven't heard about?
Not "no matter what", but generally they do get promoted as per
6.3.1.1p2.
The fact of 6.3.1.1p3 makes the integer promotion of the right hand
operand (of a shift operator) incidental.
It's not clear how
x {is unsigned short} <<= 1U
causes anything to be promoted to any signed type.
In cases where USHRT_MAX <= INT_MAX, we have...
x <<= 1u;
x = x << 1u;
x = ((int) x) << 1u;
....all being identical. The u suffix in 1u is irrelevant here, it's the
integral
promotion of x from unsigned short to int that may occur.
If, for the same premice, we instead have...
x += 1u;
x = x + 1u;
Then arithmetic conversion occurs on top of the integral promotion...
x = (unsigned) (int) x + 1u;
Whilst arithmetic conversion applies to binary +, it does not apply to
<<.
I assume you mean
x = (unsigned short)(INT_MAX/2+1) << (unsigned short)1
Given the initial premice, they have the same semantics. Even the
explicit cast to (unsigned short) will not prevent integral promotion
from applying to the left operand.
or even
x <<= 1U; [it'll promote to unsigned int and safely drop back down]
No, the two operands of shift operators are not subject to arithmetic
promotion.
But your entire POINT rides on having it be promoted to signed int if
you use 1 instead of 1U or (unsigned short)1!
No. I think you haven't yet seen the difference between integral
promotion
and arithmetic conversion.