[swift-evolution] [Pitch] Remove bit shift traps

Dave Abrahams dabrahams at apple.com
Mon Mar 21 17:52:50 CDT 2016


on Thu Mar 17 2016, Patrick Pijnappel <swift-evolution at swift.org> wrote:

> Currently, bit shifting with an amount greater than or equal to the size of
> the type traps:
>
> func foo(x: Int32) {
>   let y = x << 32 // Runtime trap (for any << or >> with amount >= 32)
> }
>
> I propose to make this not trap, and just end up with 0 (or ~0 in case of
> right-shifting a negative number):
>
>    - Unlike the traps for integer arithmetic and casts, it is obvious what
>    a bitshift past the end does as fundamentally the behavior stays the same.
>    - If the intention is to make it analogous with multiplication/division
>    by 2**n, the checks don't really change anything. Right shift are still
>    identical to divisions by 2**n. Left shifts are like multiplication by 2**n
>    but with different overflow behavior, which is already the case with the
>    current rules (e.g. Int.max << 1 doesn't trap)
>    - It could lead to bugs where users expect this to work, e.g. the
>    following crashes when the entire buffer is consumed: buffer = buffer <<
>    bitsConsumed
>    - Bitshift are often used in performance-sensitive code, and with the
>    current behavior any non-constant bit shift introduces a branch.

This is addressed in
https://github.com/apple/swift/blob/master/test/Prototypes/Integers.swift.gyb
which we intend to propose very soon.

(negative shift amounts work too).

https://github.com/apple/swift/blob/master/test/Prototypes/Integers.swift.gyb#L1628

For users who want to be sure they're not paying for any checks, there
is a masking bitshift (&<<, &>>, &<<=, &>>=).

--
-Dave



More information about the swift-evolution mailing list