> On Jul 17, 2017, at 10:06 PM, Taylor Swift via swift-evolution
> <swift-evolution@swift.org> wrote:
>
> I’ve drafted a new version of the unsafe pointer proposal based on feedback
> I’ve gotten from this thread. You can read it here
> <https://gist.github.com/kelvin13/1b8ae906be23dff22f7a7c4767f0c907>.
>
> ~~~
> Swift’s pointer types are an important interface for low-level memory
> manipulation, but the current API design is not very safe, consistent, or
> convenient. Many memory methods demand a capacity: or count: argument,
> forcing the user to manually track the size of the memory block, even though
> most of the time this is either unnecessary, or redundant as buffer pointers
> track this information natively. In some places, this design turns
> UnsafePointers into outright DangerousPointers, leading users to believe that
> they have allocated or freed memory when in fact, they have not.
>
> The current API suffers from inconsistent naming, poor usage of default
> argument values, missing methods, and excessive verbosity, and encourages
> excessively unsafe programming practices. This proposal seeks to iron out
> these inconsistencies, and offer a more convenient, more sensible, and less
> bug-prone API for Swift pointers.
>
> The previous draft
> <https://gist.github.com/kelvin13/a9c033193a28b1d4960a89b25fbffb06> of this
> proposal was relatively source-breaking, calling for a separation of
> functionality between singular pointer types and vector (buffer) pointer
> types. This proposal instead separates functionality between
> internally-tracked length pointer types and externally-tracked length pointer
> types. This results in an equally elegant API with about one-third less
> surface area.
>
> <https://gist.github.com/kelvin13/1b8ae906be23dff22f7a7c4767f0c907
> <https://gist.github.com/kelvin13/1b8ae906be23dff22f7a7c4767f0c907>>
>
> ~~~
>
> remove the capacity parameter from deallocate(capacity:) and
> deallocate(bytes:alignedTo:)
That's probably for the best.
> add unsized memory methods to UnsafeMutableBufferPointer
Yay!
> add an assign(to:count:) method to UnsafeMutablePointer and an assign(to:)
> method to UnsafeMutableBufferPointer
Sure.
> add a default value of 1 to all size parameters on UnsafeMutablePointer and
> applicable
> size parameters on UnsafeMutableRawPointer
I'm not opposed to it.
> rename copyBytes(from:count:) to copy(from:bytes:)
LGTM in the interest of consistency. I should not have caved on this the first
time around.
> bytes refers to, well, a byte quantity that is not assumed to be initialized.
> capacity refers to a strided quantity that is not assumed to be initialized.
> count refers to a strided quantity that is assumed to be initialized.
That's how I see it.
> rename count in UnsafeMutableRawBufferPointer.allocate(count:) to bytes and
> add an
> alignedTo parameter to make it
> UnsafeMutableRawBufferPointer.allocate(bytes:alignedTo:)
Memory allocation is an issue unto itself. I generally prefer your
proposed API. However...
1. Larger-than-pointer alignments aren't currently respected.
2. Users virtually never want to specify the alignment explicitly. They
just want platform alignment. Unfortunately, there's no reasonable
"maximal" alignment to use as a default. I think pointer-alignment
is an excellent default guarantee.
3. The current allocation builtins seem to presume that
allocation/deallocation can be made more efficient if the user code
specifies alignment at deallocation. I don't think
UnsafeRawBufferPointer should expose that to the user, so I agree
with your proposal. In fact, I think aligned `free` should be
handled within the Swift runtime.
Resolving these issues requires changes to the Swift runtime API and
implementation. This might be a good time to revisit that design, but
it might slow down the rest of the proposal.
> fix the ordering of the arguments in
> initializeMemory<Element>(as:at:count:to:)
I think this ordering was an attempt to avoid confusion with binding
memory where `to` refers to a type. However, it should be consistent
with `UnsafePointer.initialize`, so we need to pick one of those to
change.
> add the sized memorystate functions withMemoryRebound<Element,
> Result>(to:count:_:) to
> UnsafeMutableBufferPointer, and initializeMemory<Element>(as:at:to:count:),
> initializeMemory<Element>(as:from:count:)
> moveInitializeMemory<Element>(as:from:count:),
> and bindMemory<Element>(to:count:) to UnsafeMutableRawBufferPointer
Yay!
> add mutable overloads to non-vacating memorystate method arguments
I'm not sure removing the need for implicit casts is a goal. I did
that with the pointer `init` methods, but now I think that should be
cleaned up to reduce API surface. I think smaller API surface wins in
these cases. Is there a usability issue you're solving?
> add a init(mutating:) initializer to UnsafeMutableBufferPointer
Yes, finally.
> remove initialize<C>(from:) from UnsafeMutablePointer
Yep.
> adding an initializer
> UnsafeMutableBufferPointer<Element>.init(allocatingCount:) instead > of a
> type method to UnsafeMutableBufferPointer
For the record, I strongly prefer a type method for allocation for the reason
you mention, it has important side effects beyond simply initializingn the
pointer.
-Andy
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution