Pointers in Swift
Asked Answered
O

1

9

I'm trying to understand the use of pointers in Swift, in particular: Unsafe[Mutable]Pointer and UnsafeRaw[Mutable]Pointer. I have several questions on the subject.

  1. Is UnsafePointer <T> equal to const T * Pointer in ? and UnsafeMutablePointer <T> is equal to T * Pointer in C?

  2. What is the difference between Unsafe[Mutable]Pointer and UnsafeRaw[Mutable]Pointer?

  3. Why does this compile

func receive(pointer: UnsafePointer<Int> ) {
    print("param value is: \(pointer.pointee)")
}

var a: Int = 1
receive(pointer: &a) // prints 1

but this gives me an error?

var a: Int = 1
var pointer: UnsafePointer<Int> = &a // error : Cannot pass immutable value of type 'Int' as inout argument
Overmatter answered 22/2, 2017 at 14:27 Comment(0)
G
7
  1. Is UnsafePointer <T> equal to const T * Pointer in ? and UnsafeMutablePointer <T> is equal to T * Pointer in C?

Well, use a bridging header in a Swift app to see how the C pointers are bridged:

const int *myInt;
int *myOtherInt;

bridges to

var myInt: UnsafePointer<Int32>!
var myOtherInt: UnsafeMutablePointer<Int32>!
  1. What is the difference between Unsafe[Mutable]Pointer and UnsafeRaw[Mutable]Pointer?

Swift 3 added a UnsafeRawPointer API to replace the Unsafe[Mutable]Pointer<Void> type. Conversion between pointers of a different type is no longer allowed in Swift. Instead, the API provides interfaces (.assumingMemoryBound(to:) or .bindMemory(to:capacity:)) to bind memory to a type.

With regard to question 3, the ampersand means that the variable is inout. I don't believe you can declare a variable as inout unless it is being used by a function that directly modifies the underlying memory, but I'll let the experts correct me. Instead, use withUnsafePointer.

Thanks to Martin's helpful comment, this syntax was never valid in Swift, and there is no safe way to create "free pointers" to Swift variables.

Gym answered 22/2, 2017 at 14:49 Comment(2)
var pointer: UnsafePointer<Int> = &a was never valid, and your "workaround" is unsafe: The pointer passed to the closure of withUnsafePointer is only valid during the execution of the closure. It must not be passed to the outside of the closure. – You cannot (safely) pass pointers to Swift variables freely around.Forwardness
@MartinR Thanks, I'll edit my answer. Not really clear what the OP wanted, so I wasn't sure if they wanted safe/unsafe behavior. But it's clear they're new to pointers, better to just remove any unsafe behavior entirely.Gym

© 2022 - 2024 — McMap. All rights reserved.