[swift-evolution] Warning for possible overflow or optional

Shawn Erickson shawnce at gmail.com
Tue Feb 16 14:37:17 CST 2016


Ok one last reply to myself...

public class Int16 {
    public init(_ v: UInt8) {}
    public init(_ v: Int8) {}

    public init?(_ v: UInt16) {...on overflow return nil...}
    public init(assertValue: UInt16) {...on overflow assert...} // I think
we could just drop this
    public init(truncatingValue: UInt16) {...on overflow truncate, alway
positive...}

    public init?(_ v: Int32) {...on overflow return nil...}
    public init(assertValue: Int32) {...on overflow assert...} // I think
we could just drop this
    public init(truncatingValue: Int32) {...on overflow truncate, maintain
sign...}

    public init?(_ v: UInt32) {...on overflow return nil...}
    public init(assertValue: UInt32) {...on overflow assert...} // I think
we could just drop this
    public init(truncatingValue: UInt32) {...on overflow truncate, alway
positive...}

    ...others...

    public init(bitPattern: UInt16) {...close your eyes and copy the
bits...}
}


let unsigned32 = UInt32(UInt16.max + 50)

guard let foo = Int16(unsigned32) else {
    throw Blah ...or... assert("BOOM")
}
...do stuff...

...or...

if let foo = Int16(unsigned32) {
    ...do stuff...
}
else {
    ...handle error...
}

...or...

let foo = Int16(truncatingValue: unsigned32)
...do stuff...

...or...

let foo = Int16(assertValue: unsigned32) //again I think we could just drop
this
...do stuff unless I just went boom...


On Tue, Feb 16, 2016 at 11:57 AM Shawn Erickson <shawnce at gmail.com> wrote:

> Thinking a little more about this how about just adding failable
> constructors so it becomes easier to deal with runtime narrowing errors for
> those that need it? (that was my main issue I ran across when using these
> classes in an early project, I had to put code around things to deal with
> the edge case that the library was already obviously doing)
>
> extension UInt16 {
>     public init(_ v: UInt8)
>     public init(_ v: Int8)
>     public init(_ v: Int16)
>     public init(_ v: UInt32)                    // runtime narrowing
> check, asserts BOOOM
>     public init?(validatingValue: UInt32)       // runtime narrowing
> check, failable initializer
>     public init(truncatingBitPattern: UInt32)   // narrowing "fixup"
> initializer
>     public init(_ v: Int32)                     // runtime narrowing
> check, asserts BOOOM
>     public init?(validatingValue: UInt32)       // runtime narrowing
> check, failable initializer
>     public init(truncatingBitPattern: Int32)    // narrowing "fixup"
> initializer
>  ...
>     public init(bitPattern: Int16)              // I know what I doing!
> (aka live dangerously)
> }
>
> Ideally – to me – you would want the failable initializers to be the
> default ones available with the boom crash ones being something you could
> switch to use much like the the other special "i know what I am doing
> ones". Not sure of the naming to use for such an initializer however.
>
>
> -Shawn
>
>
> On Tue, Feb 16, 2016 at 11:28 AM Shawn Erickson <shawnce at gmail.com> wrote:
>
>> I believe you stated that you ran across at least two times that runtime
>> checks caught a narrowing error (e.g. overflow) in your recent work. I
>> support runtime checks however I feel in the case of operations that could
>> have a narrowing issue using a failable constructor makes sense. It puts
>> you control in how to deal with a narrowing error. You could assert if you
>> so want (much like what happens now) or you could deal with the edge case.
>> Swift makes the code to deal with a failable  initializer generally trivial.
>>
>> It makes you think about this very real pitfall (in some problem
>> domains) when going between numerical types.
>>
>> The issue of why are you using unsigned, etc. is orthogonal to this
>> issue. If these types exist in the language folks will use them and it
>> should be safe / consistent for them when they do.
>>
>>
>> -Shawn
>>
>> On Tue, Feb 16, 2016 at 11:11 AM David Turnbull <dturnbull at gmail.com>
>> wrote:
>>
>>> Can you show some examples where and why you use not-Int types and this
>>> is a problem? What you're suggesting will be a burden to those of us who
>>> need bitwise optimizations or work with C APIs.
>>>
>>> My last week was spent reading files with huffman coding. So I had no
>>> choice but to use bitwise operations. My experience is that Swift got this
>>> right (except for "truncatingBitPattern" taking up 25% of an 80 column
>>> line).
>>>
>>> So my question is, "why are you not using Int?" There's plenty of use
>>> cases, you just haven't stated yours so we can't understand why the current
>>> system is failing you.
>>>
>>> Safety does not mean you can easily write code that crashes once it is
>>>> deployed….
>>>
>>>
>>> var a = [Int](); a[0]=99
>>>
>>> That was pretty easy. I don't buy into this argument. If you don't want
>>> an out of bounds error, you either make sure you don't math your way out of
>>> bounds or you check every time before you subscript. I don't see why an
>>> integer conversion should be any different.
>>>
>>> -david
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160216/0b7cbfc9/attachment.html>


More information about the swift-evolution mailing list