> The main thing is just that UnsafeBufferPointer doesn't act like a pointer;
> it acts like a buffer, and a zero-element buffer turns out to be a perfectly
> useful degenerate case (and something that will happen anyway for an array
> with capacity reserved but no elements). In the cases where you use it as a
> Collection, nothing cares whether the base pointer is null.
If UnsafeBufferPointer is primarily a buffer, not a pointer, then I think it's
okay for the base address to be optional.
(And maybe it should just be called `UnsafeBuffer`.)
I really hate the "just make up an address" solution because the address is
only "valid" in the narrow, technical sense that it's properly aligned and
perhaps in an allocated page. In an empty buffer, it is never valid to actually
*access* the memory at that address. There is no data there, so you have no
business trying to do anything with the memory at that address.
If the buffer base address is nil, the situation is accurately represented: no
memory has been allocated to store this buffer's contents. If the buffer base
address is some random pointer, the buffer is telling a dangerous lie.
So I think the only way to make UnsafeBufferPointer accurately represent the
situation is with either 2i (optional okay, base address of empty buffers can
be arbitrary) or 2ii (optional okay, base address of empty buffers must be
nil). There's a certain appeal to 2ii, but I think 2i is probably more useful.
I could imagine somebody constructing an UnsafeBufferPointer that represents a
slice of the actual buffer; in that case, there really *is* a buffer at that
memory address, it's just that your slice of it doesn't have any elements. And
the ability to construct a larger buffer from a zero-sized one might be useful.
Actually, I could make an argument for a design like this:
public struct UnsafeBufferPointer<Element> {
public init(baseAddress: UnsafePointer<Element>?, count: Int)
private var _baseAddress: UnsafePointer<Element>?
/// -Precondition: the base address provided at construction
was not `nil`.
public var baseAddress: UnsafePointer<Element> {
return _baseAddress!
}
// Use these methods to safely modify a buffer pointer whether
or not it has a base address.
func rebased(at newBasePointer: UnsafePointer<Element>?) ->
UnsafeBufferPointer
func resized(to count: Int) -> UnsafeBufferPointer
}
Or even a design that used an auto-unwrapped Optional. But with the same
behavior just an `!` away, I don't think that's a good idea.
--
Brent Royal-Gordon
Architechies
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution