> 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

Reply via email to