<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br><br><div>Sent from my moss-covered three-handled family gradunza</div></div><div><br>On Jun 27, 2016, at 4:27 PM, Andrew Trick <<a href="mailto:atrick@apple.com">atrick@apple.com</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 27, 2016, at 3:35 PM, Dave Abrahams <<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">Casting from a raw pointer to a typed pointer is only more dangerous<br class="">than other raw pointer operations because it is the first step in this<br class="">sequence of operations, which is undefined:<br class=""><br class="">ptrA = rawPtr.cast(to: UnsafePointer<A>.self)<br class="">ptrA.initialize(with: A())<br class="">ptrA.deinitialize()<br class=""><br class="">ptrB = rawPtr.cast(to: UnsafePointer<B>.self)<br class="">ptrB.initialize(with: B())<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">But it's trivial to get undefined behavior without any of that. Just:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""> _ = rawPtr.load(UnsafePointer<NonTrivialType>.self)</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote></div><br class=""><div class=""><div class="">That's another way to obtain a typed pointer, but by itself it is well defined.</div></div></div></blockquote><div><br></div>Sorry, I meant to dereference that typed pointer as part of the expression. Now boom. <div><br><blockquote type="cite"><div><div class=""><div class="">This is an important point, so I want to make sure I’m getting it across.</div><div class=""><br class=""></div><div class="">The following code is well-defined:</div><div class="">```</div><div class="">ptrA = rawPtr.initialize(with: A())</div><div class="">ptrA.deinitialize()</div><div class="">ptrB = rawPtr.initialize(with: B())</div><div class="">```</div><div class="">The following code is undefined:</div><div class="">```</div><div class="">ptrA = rawPtr.cast(to: UnsafePointer<A>.self)</div><div class="">ptrA.initialize(with: A())</div><div class="">ptrA.deinitialize()</div><div class="">ptrB = rawPtr.cast(to: UnsafePointer<B>.self)</div><div class="">ptrB.initialize(with: B())</div><div class="">```</div><div class="">It is hard to spot the difference between the two styles without drawing attention to the unsafe cast.</div></div></div></blockquote>How is that substantially different from my example?</div><div><br><blockquote type="cite"><div><div class=""><div class="">I considered naming the cast `UnsafeRawPointer.bind<T>(to: T.Type)` to indicate that the allocated memory is being bound to a type for the entire duration of its allocation. But it's actually the call to `initialize` a typed pointer that binds the type.</div></div><div class=""><br class=""></div><div class="">-Andy</div></div></blockquote></div></body></html>