> On Mar 19, 2016, at 10:36, Chris Lattner <clatt...@apple.com> wrote: > > > On Mar 18, 2016, at 9:49 AM, Jordan Rose via swift-evolution > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: > >> >>> On Mar 17, 2016, at 21:08 , Russ Bishop <xen...@gmail.com >>> <mailto:xen...@gmail.com>> wrote: >>> >>> 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 <mailto:swift-evolution@swift.org>> wrote: >>>> >>>> <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). >> >> The important use case here is that "array.withUnsafeBufferPointer" should >> always do something (i.e. it usually can't just skip the closure), and it >> turns out it's easiest if the zero-element case is treated the same as >> everything else. When converting over the standard library I found that very >> few of them wanted to do something different in the zero-element case, and >> then it would be bad to force Array to allocate memory just to not use it. >> That is, there aren't actually any clients interested in knowing whether the >> base address is valid, and all of the ones that do have to think about it >> (because they use it directly) aren't getting any value out of it. > > Why would you have to allocate memory for this case? The pointer only needs > to be non-null, not valid and dereferencable. You could use the address of a > global or even 0x1.
I think it's important to preserve alignment; LLVM will sometimes optimize based on this. Jordan
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution