I’m very much +1 on this idea.

> On Mar 17, 2016, at 6:59 PM, Jordan Rose via swift-evolution 
> <swift-evolution@swift.org> wrote:

> I consider this a bit more difficult to understand than the original code, at 
> least at a glance. We should therefore add new initializers of the following 
> form:
> 
> init?<OtherPointee>(_ otherPointer: UnsafePointer<OtherPointee>?) {
>   guard let nonnullPointer = otherPointer else {
>     return nil
>   }
>   self.init(nonnullPointer)
> }
> The body is for explanation purposes only; we'll make sure the actual 
> implementation does not require an extra comparison.
> 
> (This would need to be an overload rather than replacing the previous 
> initializer because the "non-null-ness" should be preserved through the type 
> conversion.)
> 
> The alternative is to leave this initializer out, and require the nil case to 
> be explicitly handled or mapped away.
> 
> 

This should definitely be included. Everyone is used to “casting” by calling 
the appropriate initializers, and 
UnsafePointer<SpecificType>(someUnsafeVoidPointer) maps directly to what a 
C/Objective-C programmer would expect.


>  
> <https://github.com/jrose-apple/swift-evolution/tree/optional-pointers#open-issue-unsafebufferpointer>Open
>  Issue: UnsafeBufferPointer
> 
> The type UnsafeBufferPointer represents a bounded typed memory region with no 
> ownership or lifetime semantics; it is logically a bare typed pointer (its 
> baseAddress) and a length (count). For a buffer with 0 elements, however, 
> there's no need to provide the address of allocated memory, since it can't be 
> read from. Previously this case would be represented as a nil base address 
> and a count of 0.
> 
> With optional pointers, this now imposes a cost on clients that want to 
> access the base address: they need to consider the nil case explicitly, where 
> previously they wouldn't have had to. There are several possibilities here, 
> each with their own possible implementations:
> 
> Like UnsafePointer, UnsafeBufferPointer should always have a valid base 
> address, even when the count is 0. An UnsafeBufferPointer with a 
> potentially-nil base address should be optional.
> 
> UnsafeBufferPointer's initializer accepts an optional pointer and becomes 
> failable, returning nil if the input pointer is nil.
> 
> UnsafeBufferPointer's initializer accepts an optional pointer and synthesizes 
> a non-null aligned pointer value if given nil as a base address.
> 
> UnsafeBufferPointer's initializer only accepts non-optional pointers. Clients 
> such as withUnsafeBufferPointermust synthesize a non-null aligned pointer 
> value if they do not have a valid pointer to provide.
> 
> UnsafeBufferPointer's initializer only accepts non-optional pointers. Clients 
> using withUnsafeBufferPointermust handle a nil buffer.
> 
> UnsafeBufferPointer should allow nil base addresses, i.e. the baseAddress 
> property will be optional. Clients will need to handle this case explicitly.
> 
> UnsafeBufferPointer's initializer accepts an optional pointer, but no other 
> changes are made.
> 
> UnsafeBufferPointer's initializer accepts an optional pointer. Additionally, 
> any buffers initialized with a count of 0 will be canonicalized to having a 
> base address of nil.
> 
> I'm currently leaning towards option (2i). Clients that expect a pointer and 
> length probably shouldn't require the pointer to be non-null, but if they do 
> then perhaps there's a reason for it. It's also the least work.
> 
> Chris (Lattner) is leaning towards option (1ii), which treats 
> UnsafeBufferPointer similar to UnsafePointer while not penalizing the common 
> case of withUnsafeBufferPointer.
What’s the use of an UnsafeBufferPointer with zero count? Semantically that is 
making a claim that it can’t back up (“I have allocated memory at location X” 
which isn’t compatible with the idea of “zero count/size").

Without knowing more context I’d strongly favor (1i). If an array is empty the 
natural expectation for withUnsafeBufferPointer is you get 
UnsafeBufferPointer<Element>? = nil, which follows the behavior of the rest of 
the language and things like guard let make it trivial to handle properly. If 
someone really has a problem with it they can add ifUnsafeBufferPointer() that 
returns a non-optional pointer and skips executing the closure if the Array is 
empty (which is the behavior of your standard for loop).


Russ



_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to