<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 4, 2016, at 7:52 PM, Jacob Bandes-Storch &lt;<a href="mailto:jtbandes@gmail.com" class="">jtbandes@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">This is the first version of this proposal which I've had time to read. I like it a lot overall. If I have some more time, I may try pulling the branch and writing some code with it to see how it feels. (If we could get a toolchain built from the branch, that might help others review it.)</div></div></div></blockquote><div><br class=""></div><div>The latest UnsafeRawPointer definition is on this branch:</div><div><a href="https://github.com/atrick/swift/tree/rawptr" class="">https://github.com/atrick/swift/tree/rawptr</a></div><div><br class=""></div><div>I plan to update it with the latest round of feedback soonish and send out a PR.</div><div>Unfortunately, the type system/stdlib changes are not on that branch, so you won't get any implicit conversions.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">Here are a handful of minor comments:</div><div class=""><br class=""></div><div class="">- Naming: "bindMemory(to:capacity:)", being "verb-ish", seems incongruous with "assumingMemoryBound(to:)" and "withMemoryRebound(to:capacity:_:)". How about "bindingMemory(to:capacity:)” ?</div></div></div></blockquote><div><br class=""></div><div><div>DaveA is right, "bind" is active, "assumingMemoryBound" is passive. "withMemoryRebound" temporarily rebinds the type and implies that the closure may mutate state.</div><div><br class=""></div><div></div></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class="">- Would it be possible for "+(UnsafeRawPointer, Int) -&gt; UnsafeRawPointer" to accept any Integer or FixedWidthInteger, rather than only Int?</div></div></div></div></blockquote><div><br class=""></div><div><div>I'm not sure what all the tradeoffs are, but I don't think we want to index memory with non-Int sized integers. I think the user should be required to convert, which may trap.</div></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class="">- Why allow/encourage multiple calls to bindMemory on the same RawPointer? These APIs do a good job of making aliasing explicit by introducing data dependencies between pointers (you can only use a typed pointer after obtaining it from a raw pointer, and you can recover the raw pointer for later use by deinitializing the typed pointer). So, I would think the guidelines should prefer bindMemory to be used only once on a particular RawPointer value.</div></div></div></div></blockquote><div><br class=""></div><div>DaveA's answer was good. "bindMemory" is not really encouraged by the API. It's just mentioned a lot in the proposal because the semantics are interesting.</div><div><br class=""></div><div>"bindMemory" is important because it's the only safe way to reinterpret in-memory values. So you need to use it to pass a UInt8 array off as a CChar, and so forth, which is actually quite common.</div><div><br class=""></div><div>It is certainly encouraged more than unsafeBitCast(ptr, to: ...) because `bindMemory` is actually safe as long as you know the layout of the types and don't reuse your old typed pointers.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class="">And minor notes about the proposal itself:</div><div class=""><br class=""></div><div class="">- strideof(Int.self) is used in most examples, but sizeof(Int.self) appears in one of them (the "normalLifetime()" example).</div></div></div></div></blockquote><div><br class=""></div><div>That example is actually allocating memory for a single value. Should it be changed to `strideof`? If so, then what's the point of `sizeof`?</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class="">- I think there must be a mistake in this example, because pA is already bound and bindMemory was only defined for untyped RawPointers:</div><div class=""><br class=""></div><div class=""><div class="">&nbsp; &nbsp; func testInitAB() {</div><div class="">&nbsp; &nbsp; &nbsp; // Get a raw pointer to (A, B).</div><div class="">&nbsp; &nbsp; &nbsp; let p = initAB()</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; &nbsp; let pA = p.bindMemory(to: A.self, capacity: 1)</div><div class="">&nbsp; &nbsp; &nbsp; printA(pA)</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; &nbsp; printB((pA + 1).bindMemory(to: B.self, capacity: 1)) &nbsp; //&lt;&lt;&lt; should this be (p+1) rather than (pA+1)?</div><div class="">&nbsp; &nbsp; }</div></div></div></div></div></blockquote><div><br class=""></div><div>Thanks. That was supposed to be cast to raw pointer like the other examples:</div><div><br class=""></div><div>&nbsp; // Knowing the `B` has the same alignment as `A`...</div><div>&nbsp; printB(UnsafeRawPointer(pA + 1).bindMemory(to: B.self, capacity: 1))</div><div class=""><br class=""></div><div class="">-Andy</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class="gmail_extra"><br class=""></div><div class="gmail_extra"><div class=""><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr" class=""><div class="">Jacob<br class=""></div></div></div></div>
<br class=""><div class="gmail_quote">On Mon, Jul 4, 2016 at 3:32 PM, Andrew Trick via swift-evolution <span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 28, 2016, at 11:05 PM, Chris Lattner &lt;<a href="mailto:clattner@apple.com" target="_blank" class="">clattner@apple.com</a>&gt; wrote:</div><br class=""><div class=""><div class="">Hello Swift community,<br class=""><br class="">The review of “SE-0107: UnsafeRawPointer API” begins now and runs through July 4, 2016. The proposal is available here:<br class=""><br class=""><span style="white-space:pre-wrap" class="">        </span><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md" target="_blank" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md</a><br class=""></div></div></blockquote></div><div class=""><br class=""></div><div class="">I've revised the proposal again based on extremely helpful feedback from DaveA and Jordan.</div><div class=""><br class=""></div><div class="">This revision expands on the concept of formally binding the memory type that I was recently working on with Dmitri. Now we can clearly define pre and post conditions on memory operations and pointer casts that can be used to prove the type safety. The model is now simpler, more complete, and easy to reason about locally. This will help developers reason about correctness and make it easy to implement a sanitizer that verifies the type safety of UnsafePointer operations.</div><div class=""><br class=""></div><div class="">Adding safety to pointer "casts" made it possible for me to actually simplify the allocation and initialization APIs. I think both camps, convenience and safety, will be happy.</div><div class=""><br class=""></div><div class="">You can see what changed in this pull request:</div><div class=""><a href="https://github.com/apple/swift-evolution/pull/408" target="_blank" class="">https://github.com/apple/swift-evolution/pull/408</a></div><div class=""><br class=""></div><div class="">Brief summary:</div><div class=""><br class=""></div><div class="">- Memory is dynamically bound to a single type.</div><div class=""><br class=""></div><div class="">- All typed access to memory, whether via a typed pointer or regular</div><div class="">&nbsp; language construct, must be consistent with the memory's bound type</div><div class="">&nbsp; (the access type must be related to the bound type). Typed access</div><div class="">&nbsp; includes initialization, assignment, or deinitialization via a typed</div><div class="">&nbsp; pointer.</div><div class=""><br class=""></div><div class="">- Memory remains bound after being deinitialized.</div><div class=""><br class=""></div><div class="">- Memory is implicitly bound or rebound to a type by initializing it</div><div class="">&nbsp; via a raw pointer.</div><div class=""><br class=""></div><div class="">- A separate API now exists for explicity binding or rebinding memory</div><div class="">&nbsp; to a type. This allows binding to be decoupled from initialization</div><div class="">&nbsp; for convenience and efficiency. It also supports safe</div><div class="">&nbsp; interoperability between APIs that used different, but layout</div><div class="">&nbsp; compatible types.</div><div class=""><br class=""></div><div class="">- Using an API that accesses memory as a different type can now be</div><div class="">&nbsp; accomplished by rebinding the memory. This effectively changes the</div><div class="">&nbsp; type of any initialized values in memory. The compiler is still</div><div class="">&nbsp; permitted to assume strict aliasing for accesses on either side of</div><div class="">&nbsp; the operation that rebinds memory.</div><div class=""><br class=""></div><div class="">Andy</div></div><br class="">_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
<br class=""></blockquote></div><br class=""></div></div></div>
</div></blockquote></div><br class=""></body></html>