Is parent object alive for duration of `withUnsafePointer(to:)` instance member?

if i have a class

class Foo 
{
    var value:Bar

    ...
    deinit 
    {
        // deinitialize `self.value`
    }
}

and i take an unsafe pointer to value

withUnsafePointer(to: self.value) 
{
    ...
}

is the instance of Foo guaranteed to be alive for the duration of the withUnsafePointer call? or must it be wrapped in a withExtendedLifetime(_:) fence?

Today, withUnsafePointer(to:) does no lifetime extension, and for that matter neither does withUnsafeMutablePointer(to:). The lifetime behavior comes entirely from the &, i.e. inout semantics, which applies whenever you use & to pass something as a pointer. So in your example, there’s no inout, and thus the formal behavior here is:

  1. Read the property
  2. Pass that value to withUnsafePointer(to:)
  3. withUnsafePointer(to:) gets the address of its parameter (which may mean storing it into a temporary)
  4. That address gets passed to the callback as a pointer

Optimization will usually collapse steps 1-3 so that you end up with the address of the stored property instead of some temporary, but it’s not part of the formal semantics. This isn’t going to be a dangling pointer, but neither is the base object guaranteed to stay alive.

Now, these functions might be special enough that they should be blessed with additional behavior, but today they are not.

3 Likes

@lorentey has proposed stable storage attribute for stored properties. If Swift had such a thing, then you could guarantee that an inout gets the stored property address, not a temporary address.

1 Like
Terms of Service

Privacy Policy

Cookie Policy