[swift-users] Pointer conversions between different sockaddr types

Martin R martinr448 at gmail.com
Wed Aug 17 12:55:19 CDT 2016


I am trying to figure out how to work correctly with the new UnsafeRawPointer API (from https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md ).

Here my concrete example: The connect() system call takes a (const struct sockaddr *address) parameter, but one actually passes the address of a struct sockaddr_in or sockaddr_in6 (or ...).

In Swift 2.2 this could be done as

    var addr = sockaddr_in() // or sockaddr_in6()
    // fill addr fields ...
    let sock = socket(PF_INET, SOCK_STREAM, 0)

    let result = withUnsafePointer(&addr) {
        connect(sock, UnsafePointer($0), socklen_t(strideofValue(addr)))
    }

With the latest Swift from Xcode 8 beta 6, unsafe pointers cannot be simply initialized from a different kind of unsafe pointer anymore. I came up with two different solutions: 

    let result = withUnsafePointer(to: &addr) {
        connect(sock,
                UnsafeRawPointer($0).assumingMemoryBound(to: sockaddr.self),
                socklen_t(MemoryLayout<sockaddr_in>.stride))
    }

or

    let result = withUnsafePointer(to: &addr) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
            connect(sock, $0, socklen_t(MemoryLayout<sockaddr_in>.stride))
        }
    }

which both compile and run correctly.

My questions are:
- Are both solutions correct, should one be preferred, or are both wrong?
- Can the same be achieved simpler?

Thanks,
Martin





More information about the swift-users mailing list