> On Aug 9, 2017, at 8:51 AM, Taylor Swift <kelvin1...@gmail.com> wrote:
>
>
>
> On Wed, Aug 9, 2017 at 2:34 AM, Andrew Trick <atr...@apple.com
> <mailto:atr...@apple.com>> wrote:
>
>> On Aug 8, 2017, at 11:10 PM, Taylor Swift <kelvin1...@gmail.com
>> <mailto:kelvin1...@gmail.com>> wrote:
>>
>>
>> On Wed, Aug 9, 2017 at 1:51 AM, Andrew Trick <atr...@apple.com
>> <mailto:atr...@apple.com>> wrote:
>>
>>> On Aug 8, 2017, at 8:44 PM, Taylor Swift <kelvin1...@gmail.com
>>> <mailto:kelvin1...@gmail.com>> wrote:
>>>
>>> cool,, as for UnsafeMutableRawBufferPointer.copy(from:bytes:), I cannot
>>> find such a function anywhere in the API. There is copyBytes(from:)
>>> <https://developer.apple.com/documentation/swift/unsafemutablerawbufferpointer/2635415-copybytes>,
>>> but the documentation is messed up and mentions a nonexistent count:
>>> argument over and over again. The documentation also doesn’t mention what
>>> happens if there is a length mismatch, so users are effectively relying on
>>> an implementation detail. I don’t know how to best resolve this.
>>
>> We currently have `UnsafeMutableRawBufferPointer.copyBytes(from:)`. I don’t
>> think your proposal changes that. The current docs refer to the `source`
>> parameter, which is correct. Docs refer to the parameter name, not the label
>> name. So `source.count` is the size of the input. I was pointing out that it
>> has the semantics: `debugAssert(source.count <= self.count)`.
>>
>> Your proposal changes `UnsafeRawPointer.copyBytes(from:count:)` to
>> `UnsafeRawPointer.copy(from:bytes:)`. Originally we wanted to those API
>> names to match, but I’m fine with your change. What is more important is
>> that the semantics are the same as `copyBytes(from:)`. Furthermore, any new
>> methods that you add that copy into a raw buffer (e.g.
>> initializeMemory(as:from:count:)) should have similar behavior.
>>
>>
>> I’m fine with switching to taking the count from the source, though I think
>> taking the count from the destination is slightly better because 1) the use
>> cases I mentioned in the other email, and 2) all the other memorystate
>> functions use self.count instead of source.count, if they take a source
>> argument. But being consistent with the raw pointer version is more
>> important.
>
> If it’s copying from a buffer it should not take a count, if it’s copying
> from a pointer it obviously needs to take a count. What I mean by the two
> versions being named consistently is simply that they’re both named
> `copyBytes`. That really isn’t important though. The overflow/underflow
> semantics being consistent are important.
>
> (Incidentally, the reason “bytes” needs to be in the somewhere name is
> because this method isn’t capable of copying nontrivial values)
>
>> Should the methods that don’t deal with raw buffers also be modified to use
>> the source argument (i.e. UnsafeMutableBufferPointer.initialize(from:))?
>
> I’m not sure what you mean by this. It also allows the destination to be
> larger than the source. Initializing from a sequence does not trap on
> overflow because we can’t guarantee the size of the sequence ahead of time.
> When I talk about consistent overflow/underflow semantics, I’m only talking
> about initializing one unsafe buffer/pointer from another unsafe
> buffer/pointer.
>
>> Also, was there a reason why UnsafeMutableRawBufferPointer.copyBytes(from:)
>> uses the source’s count instead of its own? Right now this behavior is
>> “technically” undocumented behavior (as the public docs haven’t been
>> updated) so if there was ever a time to change it, now would be it.
>
> Mainly because partial initialization is more expected than dropping data on
> the floor. Ultimately, this should be whatever typical developers would
> expect the behavior to be. I would be very hesitant to change the behavior
> now though.
>
> -Andy
>
> The problem is I would expect to be able to safely call deinitialize() and
> friends after calling initialize(from:). If Element is a class type and
> initialize doesn’t fill the entire buffer range, calling deinitialize() will
> crash. That being said, since copy(from:bytes:) and copyBytes(from:) don’t do
> any initialization and have no direct counterparts in
> UnsafeMutableBufferPointer, it’s okay if they have different behavior than
> the other methods.
You astutely pointed out that the UnsafeMutableBufferPointer.deinitialize()
method is dangerous, and I asked you to add a warning to its comments. However,
given the danger, I think we need to justify adding the method to begin with.
Are there real use cases that greatly benefit from it?
We have to accept that UnsafeBufferPointer is simply not a safe API for
managing initialization and deinitialization. Adding a convenience method only
makes it less safe.
The standard library *should* vend a safe API for initializing and
deinitializing manually allocated memory. However, that will require a new
"buffer" type that wraps UnsafeBufferPointer. That will be a major design
discussion that is both out of scope for Swift 5 and makes sense to defer until
we have move-only types.
-Andy
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution