<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Aug 9, 2017, at 8:51 AM, Taylor Swift <<a href="mailto:kelvin13ma@gmail.com" class="">kelvin13ma@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><br class="Apple-interchange-newline"><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">On Wed, Aug 9, 2017 at 2:34 AM, Andrew Trick<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:atrick@apple.com" target="_blank" class="">atrick@apple.com</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Aug 8, 2017, at 11:10 PM, Taylor Swift <<a href="mailto:kelvin13ma@gmail.com" target="_blank" class="">kelvin13ma@gmail.com</a>> wrote:</div><br class="m_-4859785049460883042Apple-interchange-newline"><div class=""><div dir="ltr" class=""><br class=""><div class="gmail_extra">On Wed, Aug 9, 2017 at 1:51 AM, Andrew Trick<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:atrick@apple.com" target="_blank" class="">atrick@apple.com</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div class=""><br class=""><div class=""><span class="m_-4859785049460883042gmail-"><blockquote type="cite" class=""><div class="">On Aug 8, 2017, at 8:44 PM, Taylor Swift <<a href="mailto:kelvin13ma@gmail.com" target="_blank" class="">kelvin13ma@gmail.com</a>> wrote:</div><br class="m_-4859785049460883042gmail-m_2532167022362721963Apple-interchange-newline"><div class=""><div dir="ltr" class="">cool,, as for<span class="Apple-converted-space"> </span><span style="font-family: monospace, monospace;" class="">UnsafeMutableRawBufferPointer.<wbr class="">copy(from:bytes:)</span>, I cannot find such a function anywhere in the API. There is<span class="Apple-converted-space"> </span><a href="https://developer.apple.com/documentation/swift/unsafemutablerawbufferpointer/2635415-copybytes" target="_blank" class=""><span style="font-family: monospace, monospace;" class="">copyBytes(from:)</span></a>, but the documentation is messed up and mentions a nonexistent<span class="Apple-converted-space"> </span><span style="font-family: monospace, monospace;" class="">count:</span><span class="Apple-converted-space"> </span>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.<br class=""></div></div></blockquote><div class=""><br class=""></div></span><div class="">We currently have `UnsafeMutableRawBufferPointer<wbr class="">.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)`.</div><div class=""><br class=""></div><div class="">Your proposal changes `UnsafeRawPointer.copyBytes(fr<wbr class="">om:count:)` to `UnsafeRawPointer.copy(from:by<wbr class="">tes:)`. 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<wbr class="">:)) should have similar behavior.</div><div class=""><br class=""></div></div></div></blockquote><div class=""> </div><div class="">I’m fine with switching to taking the<span class="Apple-converted-space"> </span><span style="font-family: monospace, monospace;" class="">count</span><span class="Apple-converted-space"> </span>from the source, though I think taking the<span class="Apple-converted-space"> </span><span style="font-family: monospace, monospace;" class="">count</span><span class="Apple-converted-space"> </span>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<span class="Apple-converted-space"> </span><span style="font-family: monospace, monospace;" class="">self.count</span><span class="Apple-converted-space"> </span>instead of<span class="Apple-converted-space"> </span><span style="font-family: monospace, monospace;" class="">source.count</span>, if they take a<span class="Apple-converted-space"> </span><span style="font-family: monospace, monospace;" class="">source</span><span class="Apple-converted-space"> </span>argument. But being consistent with the raw pointer version is more important.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span>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.</div><div class=""><br class=""></div><div class="">(Incidentally, the reason “bytes” needs to be in the somewhere name is because this method isn’t capable of copying nontrivial values)</div><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">Should the methods that don’t deal with raw buffers also be modified to use the source argument (i.e. UnsafeMutableBufferPointer.<wbr class="">initialize(from:))?<br class=""></div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">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.</div><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">Also, was there a reason why<span class="Apple-converted-space"> </span><span style="font-family: monospace, monospace;" class="">UnsafeMutableRawBufferPointer.<wbr class="">copyBytes(from:)</span><span class="Apple-converted-space"> </span>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.<br class=""></div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">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.</div><div class=""><br class=""></div><div class="">-Andy</div></div></div></blockquote><div class=""><br class=""></div><div class="">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.</div></div></div></blockquote><br class=""></div><div><div>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?</div><div><br class=""></div><div>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.</div><div><br class=""></div><div>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.</div><div class=""><br class=""></div><div class="">-Andy</div></div></body></html>