<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 Dec 11, 2016, at 2:51 PM, Ray Fix via swift-users <<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Hello,</div><div class=""><br class=""></div><div class="">So bindMemory is part of the memory model and memory can only bind to one type at a time to avoid aliasing. But what does binding actually do? Is it somehow communicating with the optimizer?</div></div></div></blockquote><div><br class=""></div><div>Binding memory to a type tells the compiler what type the memory can hold. Normally that happens implicitly when you allocate memory for a particular type, so you don’t need to think about it (your memory below is implicitly bound to Int16). But if you’re playing around with raw memory/type punning and get the bound type wrong, future versions of the optimizer could “break” your code in very confusing ways.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">A tangentially related second question, in the following example:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> count = </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">3</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> mutablePointer = </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">UnsafeMutablePointer</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int16</span><span style="font-variant-ligatures: no-common-ligatures" class="">>.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3e1e81" class="">allocate</span><span style="font-variant-ligatures: no-common-ligatures" class="">(capacity: count)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">defer</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> mutablePointer.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3e1e81" class="">deallocate</span><span style="font-variant-ligatures: no-common-ligatures" class="">(capacity: count)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> mutablePointer.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3e1e81" class="">initialize</span><span style="font-variant-ligatures: no-common-ligatures" class="">(to: </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1234</span><span style="font-variant-ligatures: no-common-ligatures" class="">, count: count)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">defer</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> mutablePointer.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3e1e81" class="">deinitialize</span><span style="font-variant-ligatures: no-common-ligatures" class="">(count: count) // must I do this?</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><div class="">Is it bad form if I don’t deinitialize and go straight to deallocate? I can see where it is important for ref types (to update ref counts, etc). Is it one of those things that the optimizer can remove for the case of value types?</div></span></div></div></div></blockquote><div><br class=""></div><div>You don’t need to deinitialize trivial types—it’s semantically legal to omit the deinitialize. But it doesn’t hurt—the optimizer will remove the call. I think think it’s good form to deinitialize in examples where others are using your code as reference for best practice, or if the type isn’t obviously trivial; e.g. someone may add a reference to your previously trivial struct.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="margin: 0px; line-height: normal;" class="">Finally, if I initalize with some other means, such as with a raw buffer pointer subscript, is there any need to deinitialize? Can such memory be considered initialized if I bind it with a type?</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">// 1</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> pointer = </span><span style="font-variant-ligatures: no-common-ligatures; color: #3e1e81" class="">malloc</span><span style="font-variant-ligatures: no-common-ligatures" class="">(byteCount)</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(186, 45, 162);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">defer</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3e1e81" class="">free</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(pointer)</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><br class=""></span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> mutableRawBufferPointer = </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);" class="">UnsafeMutableRawBufferPointer</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(start: pointer, count: byteCount)</span></div></div></div></div></blockquote><div><br class=""></div>The above is essentially equivalent to:</div><div><br class=""></div><div>let mutableRawBufferPointer = UnsafeMutableRawBufferPointer.allocate(bytes: byteCount, alignedTo: 16)</div><div>// alignment depends on the platform</div><div>defer {</div><div> mutableRawBufferPointer.deallocate(bytes: byteCount, alignedTo: 16)</div><div>}</div><div><span style="font-family: Menlo; font-size: 11px;" class=""> </span><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="margin: 0px; line-height: normal;" class=""><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">for</span><span style="font-variant-ligatures: no-common-ligatures" class=""> index </span><span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">in</span><span style="font-variant-ligatures: no-common-ligatures" class=""> mutableRawBufferPointer.</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">indices</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> mutableRawBufferPointer[index] = </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">42</span><span style="font-variant-ligatures: no-common-ligatures" class=""> + </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">UInt8</span><span style="font-variant-ligatures: no-common-ligatures" class="">(index)</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div></div></div></div></blockquote><div><br class=""></div><div>This is an interesting case because you’ve initialized memory to “raw bytes”. The memory isn’t bound to any type. The documentation talks about initialized memory always being bound to a type, but the underlying assumption is that you’ve used a typed operation to initialize the memory. Assigning bytes via a raw pointer subscript or storeBytes isn’t a typed operation.</div><div><br class=""></div><div>It wouldn’t even make sense to deinitialize this memory because it doesn’t hold any typed values!</div><div><br class=""></div><div>You could bulk-reinterpret that memory as some type (without loading the values), simply by binding the memory. It is only valid to reinterpret those raw bytes as a trivial type though, so you still don’t need to deinitialize.</div><div><br class=""></div><div>The UnsafeRawPointer API specifies that copying raw bytes to/from nontrivially typed memory or is illegal. The only way to get around that would be calling down to memcpy/memmove. Similarly, reinterpreting (rebinding) trivial to nontrivial types is illegal.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal;" class="">Perhaps there is a document or proposal somewhere that talks about these things. Sorry if I missed it.</div></div></div></div></blockquote></div><div><br class=""><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md</a></div><div><a href="https://swift.org/migration-guide/se-0107-migrate.html" class="">https://swift.org/migration-guide/se-0107-migrate.html</a></div><div><br class=""></div><div>The rules are codified in API doc comments, but the language is not very user-friendly. Those API docs are being worked on, so in the future you typically won’t need to refer back to the evolution proposal just to be able to understand the comments.</div><div><br class=""></div><div>-Andy</div><div><br class=""></div><div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Thanks as always,</div><div style="margin: 0px; line-height: normal;" class="">Ray</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div></div></div>_______________________________________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""></div></blockquote></div><br class=""></body></html>