<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br></div><div>On Nov 4, 2016, at 12:16 AM, Rien &lt;<a href="mailto:Rien@Balancingrock.nl">Rien@Balancingrock.nl</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><span>Thanks Any, most informative.</span><br><span></span><br><span>So the pointer “gateway’s” are in fact ephemeral. That is good for performance.</span><br><span></span><br><span>As to the low level interfaces, are you aware of any effort that addresses the POSIX socket functions?</span><br><span>(Things like ‘addrinfo')</span><br></div></blockquote><div><br></div><div>I've seen some discussion on mailing lists and forums. &nbsp;I included a little blurb in the 3.0 migration guide. &nbsp;Search for socket API helpers in this page.&nbsp;</div><div><br></div><a href="https://swift.org/migration-guide/se-0107-migrate.html#common-use-cases">https://swift.org/migration-guide/se-0107-migrate.html#common-use-cases</a><div><br>Andy<div><br><blockquote type="cite"><div><span></span><br><span>Regards,</span><br><span>Rien</span><br><span></span><br><span>Site: <a href="http://balancingrock.nl">http://balancingrock.nl</a></span><br><span>Blog: <a href="http://swiftrien.blogspot.com">http://swiftrien.blogspot.com</a></span><br><span>Github: <a href="http://github.com/Swiftrien">http://github.com/Swiftrien</a></span><br><span>Project: <a href="http://swiftfire.nl">http://swiftfire.nl</a></span><br><span></span><br><span></span><br><span></span><br><span></span><br><blockquote type="cite"><span>On 04 Nov 2016, at 06:24, Andrew Trick &lt;<a href="mailto:atrick@apple.com">atrick@apple.com</a>&gt; wrote:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>On Nov 3, 2016, at 7:41 AM, Rien via swift-users &lt;<a href="mailto:swift-users@swift.org">swift-users@swift.org</a>&gt; wrote:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>On 03 Nov 2016, at 15:16, Manfred Schubert via swift-users &lt;<a href="mailto:swift-users@swift.org">swift-users@swift.org</a>&gt; wrote:</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>Am 02.11.2016 um 18:37 schrieb Rien &lt;<a href="mailto:Rien@Balancingrock.nl">Rien@Balancingrock.nl</a>&gt;:</span><br></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>var rawPtr = UnsafeMutableRawPointer.allocate(bytes: 2, alignedTo: 0)</span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>var widePtr = rawPtr.bindMemory(to: Int16.self, capacity: 1)</span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>widePtr.pointee = 32</span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>var narrowPtr = rawPtr.bindMemory(to: UInt8.self, capacity: 2)</span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>narrowPtr[0] = 16</span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>narrowPtr[1] = 255</span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>print(widePtr.pointee)</span><br></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>This compiles and runs as expected, but it should not be allowed if I understand things correctly. So shouldn’t it be a compile time error or crash at runtime? If not, what do I get over how it was before where I was casting to a typed pointer?</span><br></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>Why do you think it should not be allowed.</span><br></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>AFAICS everything is correct.</span><br></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>If I understand the documentation correctly, this should not be allowed, because it’s not allowed to access memory as different types at the same time. It needs to be „bound“ to the type first, and can only be bound to one type at a time, so all access as another type must be encapsulated within a closure.</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Ah, but that is not the case.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>It is important to differentiate between the “gateway” to the memory and the memory area itself.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Different programming languages/compilers have different approaches, but I believe that Swift allocates a struct for every gateway.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>widePtr and narrowPtr are two different gateways. They refer to different struct's. But the struct for each of them refers to the same memory area.</span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>In the Swift memory model, a pointer value is substitutable with any other pointer of the same value. And for efficiency, pointer values are implemented as addresses. This was an intentional design decision. For example, this is well-defined:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>func foo&lt;T: Equatable&gt;(rawPtr: UnsafeRawPointer, ptrT: UnsafePointer&lt;T&gt;) {</span><br></blockquote><blockquote type="cite"><span> &nbsp;if rawPtr == UnsafeRawPointer(ptrT) {</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;assert(rawPtr.assumingMemoryBound(to: T.self).pointee == ptrT.pointee)</span><br></blockquote><blockquote type="cite"><span> &nbsp;}</span><br></blockquote><blockquote type="cite"><span>}</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Note that assumingMemoryBound(to:) is essentially a nice way of doing unsafeBitCast, but intentional and verifiable.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span>Example: widePtr can be located at address 0x1000, narrowPtr can be allocated at address 0x2000 while the memory area both refer to (the raw memory) can be at address 0x3000</span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Swift strict aliasing means that unrelated typed accesses to memory cannot overlap in their underlying raw memory.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Our UnsafePointer value representation is not realistically ever going to depend on the Pointee type.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span>Every access to the raw memory via a gateway must follow the rules for that gateway.</span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span>Note: Some compilers may only create ephemeral gateways, but as long as the compiler checks that the acces follows the correct rules, that is not a problem.</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>This is not only very useful, but it also opens the door to better interfaces to some low level Unix APIs.</span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>I think we would want a Swift interface on top of those APIs that doesn’t rely on type punning.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>A Swift pointer value itself doesn’t provide a gateway. It is really bindMemory(to:capacity:) or withMemoryRebound(to:capacity:) that control whether typed access is well-defined at some point in the program.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>In native Swift code, interacting with the memory binding APIs will be extremely rare. Type punning is not a “normal” activity outside of use cases like network I/O and binary file formats. In those cases it probably makes more sense to use a raw pointer directly rather than binding memory to a type.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>-Andy</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>Manfred</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>_______________________________________________</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>swift-users mailing list</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span><a href="mailto:swift-users@swift.org">swift-users@swift.org</a></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span><a href="https://lists.swift.org/mailman/listinfo/swift-users">https://lists.swift.org/mailman/listinfo/swift-users</a></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Regards,</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Rien</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Site: <a href="http://balancingrock.nl">http://balancingrock.nl</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Blog: <a href="http://swiftrien.blogspot.com">http://swiftrien.blogspot.com</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Github: <a href="http://github.com/Swiftrien">http://github.com/Swiftrien</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>Project: <a href="http://swiftfire.nl">http://swiftfire.nl</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>_______________________________________________</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>swift-users mailing list</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="mailto:swift-users@swift.org">swift-users@swift.org</a></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span><a href="https://lists.swift.org/mailman/listinfo/swift-users">https://lists.swift.org/mailman/listinfo/swift-users</a></span><br></blockquote></blockquote><span></span><br></div></blockquote></div></div></body></html>