Remix.run Logo
▲ Joker_vD 3 hours ago

> Shifting the sign bit out is UB

Shifting into the sign bit is also UB. Can I please have a language that actually has bitwise operators with defined semantics? No CPUs had differentiated between SAL/SHL for more than 30 years, if that was the original justification.

I'm fine with left shift trapping on overflow. I'm fine with it just wrapping around. I'm even fine with bitwise shifts simply unapplicable to ints ("cast to unsigned first, then cast back to int"). I am not fine with an operator that invokes UB for literally half of the values of the lhs's domains.

▲uecker 2 hours ago | parent | next [-]

I was thinking about eliminating this shift-into-left bit UB. There was a previous attempt though that failed to get consensus. (but long enough ago that one could try again).

But all this signed overflow UB can be turned into traps using sanitizers. In practice, generally mandating a trap is difficult though in ISO C. My plan is to mandate this as part of a special mode, in which case I would just leave this UB in the main standard.

(One problem we also have that some special interests groups in WG14 are rather hostile to our work and the rest of the C community - so I encourage everybody who is actually using C and caring about it to join).

▲Joker_vD an hour ago | parent [-]

> I was thinking about eliminating this shift-into-left bit UB.

At least make it "change of the sign bit is UB" — if 0 shifts into the sign-bit of a positive number, or 1 shifts into the sign-bit of a negative number, that shouldn't be UB. This would make left-shifts of negative numbers well-defined, their behaviour being that of two's complement numbers. And C23 already demands two's complement from the implementations, doesn't?

> signed overflow UB can be turned into traps using sanitizers.

Well, yeah, sure, but shifting -1 one place to the left doesn't overflow, it produces -2; only shifting INT_MIN or something up to and including INT_MIN + (INT_MAX/2) would overflow.

▲dcrazy 3 hours ago | parent | prev [-]

Swift: https://developer.apple.com/documentation/swift/binaryintege...

> The << operator performs a smart shift, which defines a result for a shift of any value.

> - Using a negative value for rhs performs a right shift using abs(rhs).

> - Using a value for rhs that is greater than or equal to the bit width of lhs is an overshift, resulting in zero.

> - Using any other value for rhs performs a left shift on lhs by that amount.

And while the docs don’t say it, `Int.max << 1 == -2`. And in fact, `T.max << 1 == -2` for all `T: BinaryInteger`.