> On Mar 18, 2016, at 9:49 AM, Jordan Rose via swift-evolution > <[email protected]> wrote: > > >> On Mar 17, 2016, at 21:08 , Russ Bishop <[email protected]> wrote: >> >> I’m very much +1 on this idea. >> >>> On Mar 17, 2016, at 6:59 PM, Jordan Rose via swift-evolution >>> <[email protected]> wrote: >>> 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. -Chris
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
