Search code examples
swiftunsafe-pointers

Swift array address is not same as &array[0]


Document said:

  • An in-out expression that contains a mutable variable, property, or subscript reference of type Type, which is passed as a pointer to the address of the left-hand side identifier.
  • A [Type] value, which is passed as a pointer to the start of the array.

But when I run the following code :

func print<Type>(unsafePointer pointer: UnsafePointer<Type>) {
    print("\(pointer) ==> \(pointer.pointee) : \(Type.self)")
}

var array = [1, 2, 3, 4]
print(unsafePointer: array)
print(unsafePointer: &array[0])

I get

0x0000000104204240 ==> 1 : Int
0x00007ffeefbff440 ==> 1 : Int

Why their addresses are different?


Solution

  • Here

    print(unsafePointer: array)
    

    a pointer to the first element of the array storage is passed to the function. And here

    print(unsafePointer: &array[0])
    

    the subscript operator is called on the array (returning an Int) and the address of that (temporary) integer is passed to the function, not the address where the original array element is stored.

    That becomes more obvious if you call the functions twice:

    var array = [1, 2, 3, 4]
    
    print(unsafePointer: array)     // 0x00007ffeefbff2e0
    print(unsafePointer: array)     // 0x00007ffeefbff2e0, same as previous address
    
    print(unsafePointer: &array[0]) // 0x00007ffeefbff320
    print(unsafePointer: &array[0]) // 0x00007ffeefbff340, different from previous address
    

    In addition, passing an in-out expression to a function can make a temporary copy, see for example Swift: always copies on inout?.