<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 May 9, 2016, at 12:38 PM, Geordie Jay &lt;<a href="mailto:geojay@gmail.com" class="">geojay@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class="">I read this proposal and I'm a bit unsure what its purpose would be:<br class=""><br class="">Basically you want to prevent UnsafePointer&lt;XYZ&gt;(UnsafePointer&lt;Void&gt;) conversions and/or vice-versa? And you'd achieve this by replacing UnsafePointer&lt;Void&gt; with UnsafeBytePointer that has no bound pointer type?<br class=""></div></blockquote><div><br class=""></div><div>I want to prevent UnsafePointer&lt;U&gt;(UnsafePointer&lt;T&gt;) *except* when the destination is UnsafePointer&lt;Void&gt;.</div><div><br class=""></div><div>UnsafePointer&lt;Void&gt;(UnsafePointer&lt;T&gt;) is fine.</div><div><br class=""></div><div>UnsafeBytePointer provides two thing:</div><div>- A means to prevent the conversion above</div><div>- An API for legal type punning, which does not exist today</div><div><br class=""></div><blockquote type="cite" class=""><div class="">In one sense the change seems fine to me, but as someone who uses a lot of C APIs and a lot of CoreAudio/CoreMIDI in Swift already I can't really see what benefit it'd bring. Presumably we'd still want an option of converting UnsafeBytePointer to UnsafePointer&lt;SomeActualType&gt; for things like C function pointer callback "context"/"userInfo" uses, so it's not like we'd be preventing programmer error in that way.<br class=""></div></blockquote><div><br class=""></div><div>It’s possible to cast UnsafeBytePointer to UnsafePointer&lt;SomeActualType&gt;. I want the programmer to make their intent explicit &nbsp;by writing a cast and spelling SomeActualType at the point of the cast. In the proposal, that’s done using a labeled initializer.</div><br class=""><blockquote type="cite" class=""><div class="">Call me conservative but to me the current system seems to work as well as it can. If anything it's already enough boilerplate going through hoops converting an UnsafeMutablePointer&lt;Void&gt; into a [Float] even when I know and the C API knows perfectly well what it actually contains... Would happily be convinced otherwise about this proposal though, I'm pretty new at all this.<br class=""></div></blockquote><div><br class=""></div>I think you are asking for implicit conversions when calling C APIs. That’s good feedback. When implementing this proposal I tried to allow implicit conversions in reasonable cases, but leaned toward being conservative. I would rather see more explicit casts now and eliminate them if people find it awkward.</div><div><br class=""></div><div>I'm looking for some consensus on core aspects of the proposal, then we can take into consideration precisely which implicit conversions should be supported.</div><div><br class=""></div><div>-Andy</div><div><br class=""><blockquote type="cite" class=""><div class="">Geordie<br class=""><div class="gmail_quote"><div dir="ltr" class="">Andrew Trick via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; schrieb am Mo., 9. Mai 2016 um 20:15:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""><div class="">Hello Swift evolution,</div><div class=""><br class=""></div><div class="">I sent this to swift-dev last week. Sorry to post on two lists!</div><div class=""><br class=""></div><div class="">Swift does a great job of protecting against undefined behavior--as long as you avoid "unsafe" APIs, that is. However, unsafe APIs are important for giving developers control over implementation details and performance. Naturally, the contract between unsafe APIs and the optimizer is crucial. When a developer uses an unsafe API, the rules governing safe, well-defined behavior must be clear. On the opposite end, the optimizer must know which assumptions it can make based on those rules. Simply saying that anything goes because "unsafe" is in the name is not helpful to this effort.</div><div class=""><br class=""></div><div class="">For a long time, I've wanted these rules nailed down. We have more users taking advantage of advanced features, and more optimizations that take advantage of assumptions guided by the type system. This seems like a particularly good time to resolve UnsafePointer semantics, considering the type system and UnsafePointer work that's been going on recently. Strict aliasing is something I would like addressed. If we do nothing here, then we will end up by default inheriting C/C++ semantics, as with any language that relies on a C/C++ backend. In other words, developers will be forced to write code with technically undefined behavior and rely on the compiler to be smart enough to recognize and recover from common patterns. Or we can take advantage of this opportunity and instead adopt a sound memory model with respect to aliasing.</div><div class=""><br class=""></div><div class="">This proposal is only an RFC at this point. I'm sending it out now to allow for plenty of time for discussion (or advance warning). Keep in mind that it could change considerably before it goes up for review.</div></div><div class=""><br class=""></div><div class="">-Andy</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><h1 style="font-size:2.25em;margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.2;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255);margin-top:0px!important" class="">UnsafeBytePointer API for In-Memory Layout</h1><ul style="padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><li class="">Proposal:&nbsp;<a href="https://github.com/atrick/swift-evolution/blob/voidpointer/proposals/XXXX-unsafebytepointer.md" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" target="_blank" class="">SE-NNNN</a></li><li class="">Author(s):&nbsp;<a href="https://github.com/atrick" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" target="_blank" class="">Andrew Trick</a></li><li class="">Status:&nbsp;<span class=""><a href="https://github.com/atrick/swift-evolution/tree/voidpointer/proposals#rationale" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" target="_blank" class="">Awaiting review</a></span></li><li class="">Review manager: TBD</li></ul><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://github.com/atrick/swift-evolution/tree/voidpointer/proposals#introduction" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Introduction</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;and&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeMutable</code>&nbsp;refer to a typed region of memory, and the compiler must be able to assume that&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;element (<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">Pointee</code>) type is consistent with other access to the same memory. See&nbsp;<a href="https://github.com/atrick/swift/blob/type-safe-mem-docs/docs/TypeSafeMemory.rst" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" target="_blank" class="">proposed Type Safe Memory Access documentation</a>. Consequently, inferred conversion between&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;element types exposes an easy way to abuse the type system. No alternative currently exists for manual memory layout and direct access to untyped memory, and that leads to an overuse of&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>. These uses of&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>, which depend on pointer type conversion, make accidental type punning likely. Type punning via&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;is semantically undefined behavior and de facto undefined behavior given the optimizer's long-time treatment of&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">In this document, all mentions of&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;also apply to&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeMutablePointer</code>.</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://github.com/atrick/swift-evolution/tree/voidpointer/proposals#motivation" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Motivation</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">To avoid accidental type punning, we should prohibit inferred conversion between&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer&lt;T&gt;</code>&nbsp;and&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer&lt;U&gt;</code>&nbsp;unless the target of the conversion is an untyped or nondereferenceable pointer (currently represented as&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer&lt;Void&gt;</code>).</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">To support this change we should introduce a new pointer type that does not bind the type of its&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">Pointee</code>. Such a new pointer type would provide an ideal foundation for an API that allows byte-wise pointer arithmetic and a legal, well-defined means to access an untyped region of memory.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">As motivation for such an API, consider that an&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer&lt;Void&gt;</code>&nbsp;or&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">OpaquePointer</code>&nbsp;may be currently be obtained from an external API. However, the developer may know the memory layout and may want to read or write elements whose types are compatible with that layout. This a reasonable use case, but unless the developer can guarantee that all accesses to the same memory location have the same type, then they cannot use&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;to access the memory without risking undefined behavior.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">An&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;example, using a new proposed API is included below.</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://github.com/atrick/swift-evolution/tree/voidpointer/proposals#proposed-solution" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Proposed solution</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Introduce an&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;type along with an API for obtaining a&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;value at a relative byte offset and loading and storing arbitrary types at that location.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Statically prohibit inferred&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;conversion while allowing inferred&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;to&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>conversion.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;meets multiple requirements:</p><ol style="padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><li class="">An untyped pointer to memory</li><li class="">Pointer arithmetic within byte-addressable memory</li><li class="">Type-unsafe access to memory (legal type punning)</li></ol><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;will replace&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeMutablePointer&lt;Void&gt;</code>&nbsp;as the representation for untyped memory. For API clarify we could consider a typealias for&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">VoidPointer</code>. I don't think a separate&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">VoidPointer</code>&nbsp;type would be useful--there's no danger that&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;will be casually dereferenced, and don't see the danger in allowing pointer arithmetic since the only reasonable interpretation is that of a byte-addressable memory.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Providing an API for type-unsafe memory access would not serve a purpose without the ability to compute byte offsets. Of course, we could require users to convert back and forth using bitPatterns, but I think that would be awkward and only obscure the purpose of the&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;type.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">In this proposal, UnsafeBytePointer does not specify mutability. Adding an UnsafeMutableBytePointer would be straightforward, but adding another pointer type needs strong justification. I expect to get input from the community on this. If we agree that the imported type for&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">const void*</code>&nbsp;should be UnsafeBytePointer, then we probably need UnsafeMutablePointer to handle interoperability.</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://github.com/atrick/swift-evolution/tree/voidpointer/proposals#detailed-design" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Detailed design</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">The public API is shown here. For details and comments, see the&nbsp;<a href="https://github.com/atrick/swift/commits/unsafeptr_convert" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" target="_blank" class="">unsafeptr_convert branch</a>.</p><div style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;word-break:normal" class=""><span style="color:rgb(167,29,93)" class="">struct</span> UnsafeBytePointer <span style="color:rgb(167,29,93)" class="">:</span> <span style="color:rgb(0,134,179)" class="">Hashable</span>, _Pointer {

  <span style="color:rgb(167,29,93)" class="">let</span> _rawValue: Builtin<span style="color:rgb(167,29,93)" class="">.</span>RawPointer

  <span style="color:rgb(167,29,93)" class="">var</span> hashValue: <span style="color:rgb(0,134,179)" class="">Int</span> {<span style="color:rgb(167,29,93)" class="">...</span>}

  <span style="color:rgb(167,29,93)" class="">init</span><span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>(_ <span style="color:rgb(167,29,93)" class="">:</span> <span style="color:rgb(0,134,179)" class="">UnsafePointer</span><span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>)
  <span style="color:rgb(167,29,93)" class="">init</span><span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>(_ <span style="color:rgb(167,29,93)" class="">:</span> <span style="color:rgb(0,134,179)" class="">UnsafeMutablePointer</span><span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>)
  <span style="color:rgb(167,29,93)" class="">init</span>?<span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>(_ <span style="color:rgb(167,29,93)" class="">:</span> <span style="color:rgb(0,134,179)" class="">UnsafePointer</span><span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>?)
  <span style="color:rgb(167,29,93)" class="">init</span>?<span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>(_ <span style="color:rgb(167,29,93)" class="">:</span> <span style="color:rgb(0,134,179)" class="">UnsafeMutablePointer</span><span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>?)

  <span style="color:rgb(167,29,93)" class="">init</span><span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>(_ <span style="color:rgb(167,29,93)" class="">:</span> OpaquePointer<span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>)
  <span style="color:rgb(167,29,93)" class="">init</span>?<span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>(_ <span style="color:rgb(167,29,93)" class="">:</span> OpaquePointer<span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>?)

  <span style="color:rgb(167,29,93)" class="">init</span>?(bitPattern: <span style="color:rgb(0,134,179)" class="">Int</span>)
  <span style="color:rgb(167,29,93)" class="">init</span>?(bitPattern: <span style="color:rgb(0,134,179)" class="">UInt</span>)

  <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">load</span>&lt;T&gt;(_ <span style="color:rgb(167,29,93)" class="">:</span> T<span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(167,29,93)" class="">Type</span>) <span style="color:rgb(167,29,93)" class="">-&gt;</span> T

  <span style="color:rgb(167,29,93)" class="">@warn_unused_result</span>
  <span style="color:rgb(167,29,93)" class="">init</span>(allocatingBytes size: <span style="color:rgb(0,134,179)" class="">Int</span>, alignedTo: <span style="color:rgb(0,134,179)" class="">Int</span>)

  <span style="color:rgb(167,29,93)" class="">@warn_unused_result</span>
  <span style="color:rgb(167,29,93)" class="">init</span><span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>(allocatingCapacity count: <span style="color:rgb(0,134,179)" class="">Int</span>, of: T<span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(167,29,93)" class="">Type</span>)

  <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">deallocateBytes</span>(<span style="color:rgb(121,93,163)" class="">_</span> <span class="">size</span>: <span style="color:rgb(0,134,179)" class="">Int</span>, alignedTo: <span style="color:rgb(0,134,179)" class="">Int</span>)

  <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">deallocateCapacity</span>&lt;T&gt;(<span style="color:rgb(121,93,163)" class="">_</span> <span class="">num</span>: <span style="color:rgb(0,134,179)" class="">Int</span>, of: T<span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(167,29,93)" class="">Type</span>)

  <span style="color:rgb(150,152,150)" class="">// Returns a pointer one byte after the initialized memory.</span>
  <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">initialize</span>&lt;T&gt;(<span style="color:rgb(121,93,163)" class="">with</span> <span class="">newValue</span>: T, count: <span style="color:rgb(0,134,179)" class="">Int</span> <span style="color:rgb(167,29,93)" class="">=</span> <span style="color:rgb(0,134,179)" class="">1</span>) <span style="color:rgb(167,29,93)" class="">-&gt;</span> UnsafeBytePointer

  <span style="color:rgb(150,152,150)" class="">// Returns a pointer one byte after the initialized memory.</span>
  <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">initialize</span>&lt;T&gt;(from: <span style="color:rgb(0,134,179)" class="">UnsafePointer</span><span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>, count: <span style="color:rgb(0,134,179)" class="">Int</span>) <span style="color:rgb(167,29,93)" class="">-&gt;</span> UnsafeBytePointer

  <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">initializeBackward</span>&lt;T&gt;(<span style="color:rgb(121,93,163)" class="">from</span> <span class="">source</span>: <span style="color:rgb(0,134,179)" class="">UnsafePointer</span><span style="color:rgb(167,29,93)" class="">&lt;</span>T<span style="color:rgb(167,29,93)" class="">&gt;</span>, count: <span style="color:rgb(0,134,179)" class="">Int</span>)

  <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">deinitialize</span>&lt;T&gt;(_ <span style="color:rgb(167,29,93)" class="">:</span> T<span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(167,29,93)" class="">Type</span>, count: <span style="color:rgb(0,134,179)" class="">Int</span> <span style="color:rgb(167,29,93)" class="">=</span> <span style="color:rgb(0,134,179)" class="">1</span>)
}

<span style="color:rgb(167,29,93)" class="">extension</span> OpaquePointer {
  <span style="color:rgb(167,29,93)" class="">init</span>(_ <span style="color:rgb(167,29,93)" class="">:</span> UnsafeBytePointer)
}

<span style="color:rgb(167,29,93)" class="">extension</span> <span style="color:rgb(0,134,179)" class="">Int</span> {
  <span style="color:rgb(167,29,93)" class="">init</span>(bitPattern: UnsafeBytePointer)
}

<span style="color:rgb(167,29,93)" class="">extension</span> <span style="color:rgb(0,134,179)" class="">UInt</span> {
  <span style="color:rgb(167,29,93)" class="">init</span>(bitPattern: UnsafeBytePointer)
}

<span style="color:rgb(167,29,93)" class="">extension</span> UnsafeBytePointer <span style="color:rgb(167,29,93)" class="">:</span> RandomAccessIndex {
  <span style="color:rgb(167,29,93)" class="">typealias</span> Distance <span style="color:rgb(167,29,93)" class="">=</span> <span style="color:rgb(0,134,179)" class="">Int</span>

  <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">successor</span>() <span style="color:rgb(167,29,93)" class="">-&gt;</span> UnsafeBytePointer
  <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">predecessor</span>() <span style="color:rgb(167,29,93)" class="">-&gt;</span> UnsafeBytePointer
  <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">distance</span>(to <span style="color:rgb(167,29,93)" class="">:</span> UnsafeBytePointer) <span style="color:rgb(167,29,93)" class="">-&gt;</span> <span style="color:rgb(0,134,179)" class="">Int</span>
  <span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">advanced</span>(by <span style="color:rgb(167,29,93)" class="">:</span> <span style="color:rgb(0,134,179)" class="">Int</span>) <span style="color:rgb(167,29,93)" class="">-&gt;</span> UnsafeBytePointer
}

<span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">==</span> (lhs: UnsafeBytePointer, rhs: UnsafeBytePointer) <span style="color:rgb(167,29,93)" class="">-&gt;</span> <span style="color:rgb(0,134,179)" class="">Bool</span>

<span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">&lt;</span> (lhs: UnsafeBytePointer, rhs: UnsafeBytePointer) <span style="color:rgb(167,29,93)" class="">-&gt;</span> <span style="color:rgb(0,134,179)" class="">Bool</span>

<span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">+</span> (lhs: UnsafeBytePointer, rhs: <span style="color:rgb(0,134,179)" class="">Int</span>) <span style="color:rgb(167,29,93)" class="">-&gt;</span> UnsafeBytePointer

<span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">+</span> (lhs: <span style="color:rgb(0,134,179)" class="">Int</span>, rhs: UnsafeBytePointer) <span style="color:rgb(167,29,93)" class="">-&gt;</span> UnsafeBytePointer

<span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">-</span> (lhs: UnsafeBytePointer, rhs: <span style="color:rgb(0,134,179)" class="">Int</span>) <span style="color:rgb(167,29,93)" class="">-&gt;</span> UnsafeBytePointer

<span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">-</span> (lhs: UnsafeBytePointer, rhs: UnsafeBytePointer) <span style="color:rgb(167,29,93)" class="">-&gt;</span> <span style="color:rgb(0,134,179)" class="">Int</span>

<span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">+=</span> (lhs: <span style="color:rgb(121,93,163)" class="">inout</span> <span class="">UnsafeBytePointer</span>, rhs: <span style="color:rgb(0,134,179)" class="">Int</span>)

<span style="color:rgb(167,29,93)" class="">func</span> <span style="color:rgb(121,93,163)" class="">-=</span> (lhs: <span style="color:rgb(121,93,163)" class="">inout</span> <span class="">UnsafeBytePointer</span>, rhs: <span style="color:rgb(0,134,179)" class="">Int</span>)
</pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Occasionally, we need to convert from a&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;to an&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>. This should only be done in very rare circumstances when the author understands the compiler's strict type rules for&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>. Although this could be done by casting through an&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">OpaquePointer</code>, an explicit, designated unsafe pointer cast API would makes the risks more obvious and self-documenting. For example:</p><div style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;word-break:normal" class=""><span style="color:rgb(167,29,93)" class="">extension</span> <span style="color:rgb(0,134,179)" class="">UnsafePointer</span> {
  <span style="color:rgb(167,29,93)" class="">init</span>(_ from: UnsafeBytePointer, toPointee: Pointee<span style="color:rgb(167,29,93)" class="">.</span>type)
}
<span style="color:rgb(167,29,93)" class="">extension</span> <span style="color:rgb(0,134,179)" class="">UnsafeMutablePointer</span> {
  <span style="color:rgb(167,29,93)" class="">init</span>(_ from: UnsafeBytePointer, toPointee: Pointee<span style="color:rgb(167,29,93)" class="">.</span>type)
}</pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Similarly, conversion between&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;types must now be spelled with an explicitly&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">Pointee</code>&nbsp;type:</p><div style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;word-break:normal" class=""><span style="color:rgb(167,29,93)" class="">extension</span> <span style="color:rgb(0,134,179)" class="">UnsafePointer</span> {
  <span style="color:rgb(167,29,93)" class="">init</span><span style="color:rgb(167,29,93)" class="">&lt;</span>U<span style="color:rgb(167,29,93)" class="">&gt;</span>(_ from: <span style="color:rgb(0,134,179)" class="">UnsafePointer</span><span style="color:rgb(167,29,93)" class="">&lt;</span>U<span style="color:rgb(167,29,93)" class="">&gt;</span>, toPointee: Pointee<span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(167,29,93)" class="">Type</span>)
  <span style="color:rgb(167,29,93)" class="">init</span><span style="color:rgb(167,29,93)" class="">&lt;</span>U<span style="color:rgb(167,29,93)" class="">&gt;</span>(_ from: <span style="color:rgb(0,134,179)" class="">UnsafeMutablePointer</span><span style="color:rgb(167,29,93)" class="">&lt;</span>U<span style="color:rgb(167,29,93)" class="">&gt;</span>, toPointee: Pointee<span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(167,29,93)" class="">Type</span>)
}
<span style="color:rgb(167,29,93)" class="">extension</span> <span style="color:rgb(0,134,179)" class="">UnsafeMutablePointer</span> {
  <span style="color:rgb(167,29,93)" class="">init</span><span style="color:rgb(167,29,93)" class="">&lt;</span>U<span style="color:rgb(167,29,93)" class="">&gt;</span>(_ from: <span style="color:rgb(0,134,179)" class="">UnsafeMutablePointer</span><span style="color:rgb(167,29,93)" class="">&lt;</span>U<span style="color:rgb(167,29,93)" class="">&gt;</span>, toPointee: Pointee<span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(167,29,93)" class="">Type</span>)
}</pre></div><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://github.com/atrick/swift-evolution/tree/voidpointer/proposals#impact-on-existing-code" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Impact on existing code</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">The largest impact of this change is that&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">void*</code>&nbsp;and&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">const void*</code>&nbsp;are imported as UnsafeBytePointer. This impacts many public APIs, but with implicit argument conversion should not affect typical uses of those APIs.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Any Swift projects that rely on type inference to convert between&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;types will need to take action. The developer needs to determine whether type punning is necessary. If so, they must migrate to the&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;API. Otherwise, they can work around the new restriction by using a&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">toPointee</code>, or&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">mutating</code>&nbsp;label.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Disallowing inferred&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;direct conversion requires some standard library code to use an explicit&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">toPointee</code>label for unsafe conversions that may violate strict aliasing.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">All occurrences of&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">Unsafe[Mutable]Pointer&lt;Void&gt;</code>&nbsp;in the standard library are converted to&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>. e.g.&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">unsafeAddress()</code>&nbsp;now returns&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>, not&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer&lt;Void&gt;</code>.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Some occurrences of&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">Unsafe[Mutable]Pointer&lt;Pointee&gt;</code>&nbsp;in the standard library are replaced with&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>, either because the code was playing too loosely with strict aliasing rules, or because the code actually wanted to perform pointer arithmetic on byte-addresses.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">StringCore.baseAddress</code>&nbsp;changes from&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">OpaquePointer</code>&nbsp;to&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;because it is computing byte offsets and accessing the memory.&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">OpaquePointer</code>&nbsp;is meant for bridging, but should be truly opaque; that is, nondereferenceable and not involved in address computation.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">The&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">StringCore</code>&nbsp;implementation does a considerable amount of casting between different views of the&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">String</code>&nbsp;storage. The current implementation already demonstrates some awareness of strict aliasing rules. The rules are generally followed by ensuring that the&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">StringBuffer</code>&nbsp;only be accessed using the appropriate&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">CodeUnit</code>&nbsp;within Swift code. For interoperability and optimization, String buffers frequently need to be cast to and from&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">CChar</code>. This is valid as long access to the buffer from Swift is guarded by dynamic checks of the encoding type. These unsafe, but dynamically legal conversion points will now be labeled with&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">toPointee</code>.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">CoreAudio</code>&nbsp;utilities now use an UnsafeBytePointer.</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://github.com/atrick/swift-evolution/tree/voidpointer/proposals#implementation-status" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Implementation status</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">On my&nbsp;<a href="https://github.com/atrick/swift/commits/unsafeptr_convert" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" target="_blank" class="">unsafeptr_convert branch</a>, I've made most of the necessary changes to support the addition of&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>and the removal of inferred&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;conversion.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">There are a several things going on here in order to make it possible to build the standard library with the changes:</p><ul style="padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><li class=""><p style="margin-top:16px;margin-bottom:16px" class="">A new&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;type is defined.</p></li><li class=""><p style="margin-top:16px;margin-bottom:16px" class="">The type system imports&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">void*</code>&nbsp;as UnsafeBytePointer.</p></li><li class=""><p style="margin-top:16px;margin-bottom:16px" class="">The type system handles implicit conversions to UnsafeBytePointer.</p></li><li class=""><p style="margin-top:16px;margin-bottom:16px" class=""><code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>&nbsp;replaces both&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer&lt;Void&gt;</code>&nbsp;and&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeMutablePointer&lt;Void&gt;</code>.</p></li><li class=""><p style="margin-top:16px;margin-bottom:16px" class="">The standard library was relying on inferred UnsafePointer conversion in over 100 places. Most of these conversions now either take an explicit label, such as 'toPointee', 'mutating'. Some have been rewritten.</p></li><li class=""><p style="margin-top:16px;margin-bottom:16px" class="">Several places in the standard library that were playing loosely with strict aliasing or doing bytewise pointer arithmetic now use UnsafeBytePointer instead.</p></li><li class=""><p style="margin-top:16px;margin-bottom:16px" class="">Explicit labeled&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">Unsafe[Mutable]Pointer</code>&nbsp;initializers are added.</p></li><li class=""><p style="margin-top:16px;margin-bottom:16px" class="">The inferred&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">Unsafe[Mutable]Pointer</code>&nbsp;conversion is removed.</p></li></ul><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">TODO:</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Once this proposal is accepted, and the rules for casting between pointers types have been decided, we need to finish implementing the type system support. The current implementation (intentionally) breaks a few tests in pointer_conversion.swift. We also need to ensure that interoperability requirements are met. Currently, many argument casts to be explicitly labeled. The current implementation also makes it easy for users to hit an "ambiguous use of 'init'" error when relying on implicit argument conversion.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Additionally:</p><ul style="padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><li class=""><p style="margin-top:16px;margin-bottom:16px" class="">A name mangled abbreviation needs to be created for UnsafeBytePointer.</p></li><li class=""><p style="margin-top:16px;margin-bottom:16px" class="">The StringAPI tests should probably be rewritten with&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>.</p></li><li class=""><p style="margin-top:16px;margin-bottom:16px" class="">The NSStringAPI utilities and tests may need to be ported to&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code></p></li><li class=""><p style="margin-top:16px;margin-bottom:16px" class="">The CoreAudio utilities and tests may need to be ported to&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>.</p></li></ul><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://github.com/atrick/swift-evolution/tree/voidpointer/proposals#alternatives-considered" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Alternatives considered</h2><h3 style="margin-top:1em;margin-bottom:16px;line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://github.com/atrick/swift-evolution/tree/voidpointer/proposals#existing-workaround" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1.2" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Existing workaround</h3><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">In some cases, developers can safely reinterpret values to achieve the same effect as type punning:</p><div style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class=""><pre style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;word-break:normal" class=""><span style="color:rgb(167,29,93)" class="">let</span> ptrI32 <span style="color:rgb(167,29,93)" class="">=</span> <span style="color:rgb(0,134,179)" class="">UnsafeMutablePointer</span><span style="color:rgb(167,29,93)" class="">&lt;</span><span style="color:rgb(0,134,179)" class="">Int32</span><span style="color:rgb(167,29,93)" class="">&gt;</span>(allocatingCapacity: <span style="color:rgb(0,134,179)" class="">1</span>)
ptrI32[<span style="color:rgb(0,134,179)" class="">0</span>] <span style="color:rgb(167,29,93)" class="">=</span> <span style="color:rgb(0,134,179)" class="">Int32</span>()
<span style="color:rgb(167,29,93)" class="">let</span> u <span style="color:rgb(167,29,93)" class="">=</span> <span style="color:rgb(0,134,179)" class="">unsafeBitCast</span>(ptrI32[<span style="color:rgb(0,134,179)" class="">0</span>], to: <span style="color:rgb(0,134,179)" class="">UInt32</span><span style="color:rgb(167,29,93)" class="">.</span><span style="color:rgb(167,29,93)" class="">self</span>)</pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Note that all access to the underlying memory is performed with the same element type. This is perfectly legitimate, but simply isn't a complete solution. It also does not eliminate the inherent danger in declaring a typed pointer and expecting it to point to values of a different type.</p><h3 style="margin-top:1em;margin-bottom:16px;line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://github.com/atrick/swift-evolution/tree/voidpointer/proposals#discarded-alternatives" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1.2" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Discarded alternatives</h3><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">We considered adding a&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">typePunnedMemory</code>&nbsp;property to the existing&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">Unsafe[Mutabale]Pointer</code>&nbsp;API. This would provide a legal way to access a potentially type punned&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">Unsafe[Mutabale]Pointer</code>. However, it would certainly cause confusion without doing much to reduce likelihood of programmer error. Furthermore, there are no good use cases for such a property evident in the standard library.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">The opaque&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">_RawByte</code>&nbsp;struct is a technique that allows for byte-addressable buffers while hiding the dangerous side effects of type punning (a _RawByte could be loaded but it's value cannot be directly inspected).&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer&lt;_RawByte&gt;</code>&nbsp;is a clever alternative to&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeBytePointer</code>. However, it doesn't do enough to prevent undefined behavior. The loaded&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">_RawByte</code>&nbsp;would naturally be accessed via&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">unsafeBitCast</code>, which would mislead the author into thinking that they have legally bypassed the type system. In actuality, this API blatantly violates strict aliasing. It theoretically results in undefined behavior as it stands, and may actually exhibit undefined behavior if the user recovers the loaded value.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">To solve the safety problem with&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer&lt;_RawByte&gt;</code>, the compiler could associate special semantics with a&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>&nbsp;bound to this concrete generic parameter type. Statically enforcing casting rules would be difficult if not impossible without new language features. It would also be impossible to distinguish between typed and untyped pointer APIs. For example,&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer&lt;T&gt;.load&lt;U&gt;</code>&nbsp;would be a nonsensical vestige.</p><h3 style="margin-top:1em;margin-bottom:16px;line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';background-color:rgb(255,255,255)" class=""><a href="https://github.com/atrick/swift-evolution/tree/voidpointer/proposals#alternate-proposal-for-void-type" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none;display:inline-block;padding-right:2px;line-height:1.2" target="_blank" class=""><u class=""></u><u class=""></u><u class=""></u><u class=""></u></a>Alternate proposal for&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:inherit;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">void*</code>&nbsp;type</h3><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Changing the imported type for&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">void*</code>&nbsp;will be somewhat disruptive. Furthermore, this proposal currently drops the distinction between&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">void*</code>&nbsp;and&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">const void*</code>--an obvious loss of API information.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">We could continue to import&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">void*</code>&nbsp;as&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafeMutablePointer&lt;Void&gt;</code>&nbsp;and&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">const void*</code>&nbsp;as&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer&lt;Void&gt;</code>, which will continue to serve as an "opaque" untyped pointer. Converting to UnsafeBytePointer would be necesarry to perform pointer arithmetic or to conservatively handle possible type punning.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">This alternative is&nbsp;<em class="">much</em>&nbsp;less disruptive, but we are left with two forms of untyped pointer, one of which (<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer</code>) the type system somewhat conflates with typed pointers.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)" class="">Given the current restrictions of the language, it's not clear how to statically enforce the necessary rules for casting<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">UnsafePointer&lt;Void&gt;</code>&nbsp;once general&nbsp;<code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class=""></code></p></div></div></blockquote></div>
</div></blockquote></div><br class=""></body></html>