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