> 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

Reply via email to