2

Since both f and bar[42]! point to the same closure in the following code I would expect the unsafe pointers to point to the same address. They do not. Can anyone please explain why?

To clarify: I'm looking up the address returned by withUnsafePointer in Xcode using "view memory".

var bar = [Int : (() -> Void)]()

bar[42] = { print("foo") }

var f = bar[42]!

f() // prints "foo"

bar[42]!() // prints "foo"

withUnsafePointer(to: &f) { print( type(of: $0) ) ; print( $0 ) }
// UnsafePointer<(()) -> ()> 0x00007fff5fbff778 -> 0x100002100

withUnsafePointer(to: &bar[42]!) { print( type(of: $0) ) ; print($0) }
// UnsafePointer<(()) -> ()> 0x00007fff5fbff760 -> 0x100001d20

Update

I've updated the code to also print out the pointer's value:

var bar = [Int : (() -> Void)]()

bar[42] = { print("foo") }

var f = bar[42]!

f() // prints "foo"

bar[42]!() // prints "foo"

withUnsafePointer(to: &f) {
    print( type(of: $0.pointee) )
    print( $0 )
    $0.withMemoryRebound(to: Int.self, capacity: 1) {
        print("-> 0x\(String($0.pointee, radix: 16))")
    }
}

withUnsafePointer(to: &bar[42]!) {
    print( type(of: $0.pointee) )
    print($0)
    $0.withMemoryRebound(to: Int.self, capacity: 1) {
        print("-> 0x\(String($0.pointee, radix: 16))")
    }
}

Running this in Release mode gives the following output:

foo
foo
(()) -> ()
0x00007fff5fbff7d0
-> 0x100003f10
(()) -> ()
0x00007fff5fbff7d0
-> 0x100001f60

Which suggests that the compiler sees that f and bar[42]! are the same. What's confounding is that the same address can point to different copies of the same closure.

Teo Sartori
  • 1,082
  • 14
  • 24
  • Using your code in a Playground I get the same addresses for both. – Eric Aya Oct 21 '16 at 14:40
  • How very strange, so do I! – Teo Sartori Oct 21 '16 at 15:17
  • Even stranger is that if you add the following `$0.withMemoryRebound(to: Int.self, capacity: 1) { print("-> 0x\(String($0.pointee, radix: 16))") }` to the body of each of the withUnsafePointer calls you'll see the two different vars with the same address point to different addresses! – Teo Sartori Oct 21 '16 at 16:43
  • Could you run that in non-debug mode and just print these pointers? –  Oct 24 '16 at 06:29
  • Hm, so in Release mode I get the same odd result as the Playground: Two different variables with the same address, both pointing to a different place. I've updated the question with the output from the Release run. – Teo Sartori Oct 24 '16 at 09:25
  • Both `bar[42]!` and `f` are references to the same closure, but you *cannot* compare closure addresses for equality: http://stackoverflow.com/questions/24111984/how-do-you-test-functions-and-closures-for-equality. – Martin R Nov 09 '16 at 15:19

1 Answers1

0

&var is the address of the memory location that contains the address of the original memory location (i.e., it's a "pointer to a pointer").

Since ff & bar[] are two different variables, their adresses are differents too.

 ff(18)     bar(20)            coolvalue(84)
 [84]...[]...[84]...[].............[xxx]