[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
which we intend to propose very soon.

(negative shift amounts work too).


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


More information about the swift-evolution mailing list