<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 Jul 12, 2017, at 12:16 PM, Taylor Swift via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><p class="">Hi all, I’ve written up a proposal to modify the unsafe pointer API for greater consistency, safety, and ease of use.</p><p class="">~~~<br class=""></p><p class="">Swift currently offers two sets of pointer types — singular pointers such as <code class="">UnsafeMutablePointer</code>, and vector (buffer) pointers such as <code class="">UnsafeMutable</code><strong class=""><code class="">Buffer</code></strong><code class="">Pointer</code>. This implies a natural separation of tasks the two kinds of pointers are meant to do. For example, buffer pointers implement <code class="">Collection</code> conformance, while singular pointers do not.</p><p class="">However, some aspects of the pointer design contradict these implied
roles. It is possible to allocate an arbitrary number of instances from a
type method on a singular pointer, but not from a buffer pointer. The
result of such an operation returns a singular pointer, even though a
buffer pointer would be more appropriate to capture the information
about the <em class="">number</em> of instances allocated. It’s possible to subscript into a singular pointer, even though they are not real <code class="">Collection</code>s. Some parts of the current design turn UnsafePointers into downright <em class="">Dangerous</em>Pointers, leading users to believe that they have allocated or freed memory when in fact, they have not.</p><p class="">This proposal seeks to iron out these inconsistencies, and offer a
more convenient, more sensible, and less bug-prone API for Swift
pointers.</p><p class=""><<a href="https://gist.github.com/kelvin13/a9c033193a28b1d4960a89b25fbffb06" class="">https://gist.github.com/kelvin13/a9c033193a28b1d4960a89b25fbffb06</a>></p><p class="">~~~<br class=""></p></div></div></blockquote><br class=""></div><div><div>Thanks for taking time to write this up.</div><div><br class=""></div><div>General comments:</div><div><br class=""></div><div>UnsafeBufferPointer is an API layer on top of UnsafePointer. The role</div><div>of UnsafeBufferPointer is direct memory access sans lifetime</div><div>management with Collection semantics. The role of UnsafePointer is</div><div>primarily C interop. Those C APIs should be wrapped in Swift APIs that</div><div>take UnsafeBufferPointer whenever the pointer represents a C array. I</div><div>suppose making UnsafePointer less convenient would push developers</div><div>toward UnsafeBufferPointer. I don't think that's worth outright</div><div>breaking source, but gradual deprecation of convenience methods, like</div><div>`susbscript` might be acceptable.</div><div><br class=""></div><div>I have mixed feelings about stripping UnsafePointer of basic</div><div>functionality. Besides breaking source, doing that would be</div><div>inconsistent with its role as a lower API layer. The advantage would</div><div>just be descreasing API surface area and forcing developers to use a</div><div>higher-level API.</div><div><br class=""></div><div>The additive changes you propose are fairly obvious. See [SR-3088]</div><div>UnsafeMutableBufferPointer doesn't have an allocating init.</div><div><br class=""></div><div>I haven't wanted to waste review cycles on small additive</div><div>changes. It may make sense to batch them up into one coherent</div><div>proposal. Here are a few more to consider.</div><div><br class=""></div><div>- [SR-3929] UnsafeBufferPointer should have init from mutable</div><div>- [SR-4340] UnsafeBufferPointer needs a withMemoryRebound method</div><div>- [SR-3087] No way to arbitrarily initialise an Array's storage</div><div><br class=""></div><div>Point by point:</div><div><br class=""></div><div>> drop the capacity parameter from UnsafeMutablePointer.allocate() and deallocate().</div><div><br class=""></div><div>I do not agree with removing the capacity parameter and adding a</div><div>single-instance allocation API. UnsafePointer was not designed for</div><div>single instances, it was primarily designed for C-style arrays. I</div><div>don't see the value in providing a different unsafe API for single</div><div>vs. multiple values.</div><div><br class=""></div><div>I agree the primary allocation API should be</div><div>UnsafeMutableBufferPointer.allocate(capacity:). There is an argument</div><div>to be made for removing UnsafeMutablePointer.allocate(capacity:)</div><div>entirely. But, as Michael Ilseman pointed out, that would involve</div><div>reevaluating several other members of the UnsafePointer API. I think</div><div>it's reasonable for UnsafePointer to retain all its functionality as a</div><div>lower level API.</div><div><br class=""></div><div>I don't understand what is misleading about</div><div>UnsafePointer.deallocate(capacity:). It *is* inconvenienent for the</div><div>user to keep track of memory capacity. Presumably that was done so</div><div>either the implementation can move away from malloc/free or some sort</div><div>of memory tracking can be implemented on the standard library</div><div>side. Obviously, UnsafeBufferPointer.deallocate() would be cleaner in</div><div>most cases.</div><div><br class=""></div><div>> add an allocate(count:) type method to UnsafeMutableBufferPointer</div><div><br class=""></div><div>`capacity` should be used for allocating uninitialized memory not</div><div>`count`. `count` should only refer to a number of initialized objects!</div><div><br class=""></div><div>> add a deallocate() instance method to UnsafeMutableBufferPointer</div><div><br class=""></div><div>Yes, of course! I added a mention of that in SR-3088.</div><div><br class=""></div><div>> remove subscripts from UnsafePointer and UnsafeMutablePointer</div><div><br class=""></div><div>It's often more clear to perform arithmetic on C array indices rather</div><div>than pointers. That said, I'm happy to push developers to use</div><div>UnsafeBufferPointer whenever that have a known capacity. To me, this</div><div>is a question of whether the benefit of making a dangerous thing less</div><div>convenient is worth breaking source compatibility.</div><div class=""><br class=""></div><div class="">-Andy</div></div><br class=""></body></html>