[swift-users] Pointer conversions between different sockaddr types

Michael Ferenduros mike.ferenduros at gmail.com
Fri Aug 19 18:49:43 CDT 2016

> > On Aug 18, 2016, at 12:28 AM, Quinn The Eskimo! via swift-users <swift-users at swift.org> wrote: 
> > 
> > 
> > On 17 Aug 2016, at 18:55, Martin R via swift-users <swift-users at swift.org> wrote: 
> > 
> >> - Are both solutions correct, should one be preferred, or are both wrong? 
> > 
> > Your `withMemoryRebound` solution is correct. 
> Absolutely, withMemoryRebound is always safe. You can use it whenever you just need to reinterpret memory at a call site and know the number of values stored that memory location. In this case it’s “easy" because you’re dealing a single sockaddr_in. The UnsafeRawPointer proposal is the definitive reference 
> https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md <https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md> But this migration guide is more approachable… it’s still WIP: 
> https://gist.github.com/atrick/0283ae0e284610fd21ad6ed3f454a585

I’m running into the same issues, which is making me wonder withMemoryRebound - socket functions expect an UnsafePointer<sockaddr>, but the thing pointed to can actually be larger than a sockaddr (eg. sockaddr_in6 or sockaddr_storage). Is withMemoryRebound safe to use to cast pointers to differently-sized structures? In the case of UnsafeMutablePointer<sockaddr> it seems like you’re lying to the API about what memory may be modified… But if withMemoryRebound isn’t about providing that guarantee, what does it actually do vs eg. a dumb cast via OpaquePointer?

> >> - Can the same be achieved simpler? 
> > 
> > Not without introducing a layer of abstraction. 
> > 
> > In my case I introduced an abstract `Address` type (basically a wrapper around `sockaddr_storage`) and then added a method to that object which calls a closure with the right parameters (actually, multiple such methods, depending on whether I’m calling something like `connect` which takes an address, or `getpeername`, which returns one). This approach concentrates all the ugly in one place, making the rest of my BSD Sockets code much cleaner. 
> This is an annoying UpdatePointer migration case because it falls under the category of misbehaving C APIs that we deliberately don't want to encourage in Swift. The only good answer is to provide a Swift wrapper on top of the socket API as Quinn has done. It would be nice to post that code at some point so users of the socket API can copy-paste into their project. -Andy

I do something similar in a sockaddr_in6 extension here, but it’s not great code at this point and not suggested for use: https://github.com/mike-ferenduros/SwiftySockets

PS: Apologies for the broken reply-chain, I just subscribed to the list and I missed the mail I’m replying to.

More information about the swift-users mailing list