[Discussion] Cleaning up stdlib pointer and buffer routines (Open Issues Affecting Standard Library API Stability)


(Erica Sadun) #1

Starting a grouped discussion about these four:

* The global function withUnsafe[Mutable]Pointer(&x) should have an argument label “to”. (https://bugs.swift.org/browse/SR-1937 rdar://problem/26529498.)

I think this one is clear and obvious.

* Remove unsafeAddressOf. "We are not aware of any real use cases for it. If there are any, it should be renamed to unsafeAddress(of:) to follow the guidelines." (https://bugs.swift.org/browse/SR-1957 rdar://problem/18589289)

* Consider renaming or eliminating ManagedProtoBuffer. "The reason why ManagedProtoBuffer exists is to give the users an extra bit of type safety inside of the closure passed to ManagedBuffer.create(). This closure receives the ManagedBuffer instance and returns the initial value that is stored in the buffer (the header part of the buffer). We are passing the ManagedBuffer as ManagedProtoBuffer to prevent the closure from reading the uninitialized value property. Maybe this extra bit of safety is not worth the API surface complexity." (https://bugs.swift.org/browse/SR-1955 rdar://problem/26012924 rdar://problem/27118532.")

* withUnsafePointer shouldn't take its argument as inout. (https://bugs.swift.org/browse/SR-1956 rdar://problem/25019862) Note: "Jordan has objections, see https://bugs.swift.org/browse/SR-1956"

-- E


(Jacob Bandes-Storch) #2

* *Remove unsafeAddressOf*. "We are not aware of any real use cases for
it. If there are any, it should be renamed to unsafeAddress(of:) to follow
the guidelines." (https://bugs.swift.org/browse/SR-1957
rdar://problem/18589289)

Oops, I just responded to this on another thread. Pasting:

It's minor, but I use unsafeAddressOf regularly for writing `description`
methods:

    var description: String {
        return "<\(self.dynamicType): \(unsafeAddressOf(self))>{ more info
here... }"
    }

I guess this would be covered by some generalized solution for format
specifiers in string interpolations, but I gather that won't happen for
quite a while...


(Charlie Monroe) #3

* Remove unsafeAddressOf. "We are not aware of any real use cases for it. If there are any, it should be renamed to unsafeAddress(of:) to follow the guidelines." (https://bugs.swift.org/browse/SR-1957 rdar://problem/18589289 <rdar://problem/18589289>)

I've mentioned on the bug report a few places in my code where I use the unsafeAddressOf - it can be used nicely to log the pointer to an instance - useful for debugging and is much shorter than

Unmanaged.passUnretained(x).toOpaque()

as Dmitri suggested - and clearer in a way - you are logging an address, you shouldn't have to deal with retain/unretained at all.

I'm definitely for keeping it around, the renaming seems good to me. Alternative to renaming it is to move this under Unmanaged:

Unmanaged.address(of: obj)

BTW Xcode 8 already sees it as renamed to unsafeAddress(of:).

···

* Consider renaming or eliminating ManagedProtoBuffer. "The reason why ManagedProtoBuffer exists is to give the users an extra bit of type safety inside of the closure passed to ManagedBuffer.create(). This closure receives the ManagedBuffer instance and returns the initial value that is stored in the buffer (the header part of the buffer). We are passing the ManagedBuffer as ManagedProtoBuffer to prevent the closure from reading the uninitialized value property. Maybe this extra bit of safety is not worth the API surface complexity." (https://bugs.swift.org/browse/SR-1955 rdar://problem/26012924 <rdar://problem/26012924> rdar://problem/27118532 <rdar://problem/27118532>.")

* withUnsafePointer shouldn't take its argument as inout. (https://bugs.swift.org/browse/SR-1956 rdar://problem/25019862 <rdar://problem/25019862>) Note: "Jordan has objections, see https://bugs.swift.org/browse/SR-1956"

-- E
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Erica Sadun) #4

* Remove unsafeAddressOf. "We are not aware of any real use cases for it. If there are any, it should be renamed to unsafeAddress(of:) to follow the guidelines." (https://bugs.swift.org/browse/SR-1957 rdar://problem/18589289 <rdar://problem/18589289>)

I've mentioned on the bug report a few places in my code where I use the unsafeAddressOf - it can be used nicely to log the pointer to an instance - useful for debugging and is much shorter than

Unmanaged.passUnretained(x).toOpaque()

as Dmitri suggested - and clearer in a way - you are logging an address, you shouldn't have to deal with retain/unretained at all.

I'm definitely for keeping it around, the renaming seems good to me. Alternative to renaming it is to move this under Unmanaged:

Unmanaged.address(of: obj)

BTW Xcode 8 already sees it as renamed to unsafeAddress(of:).

Can you take lead on this batch of items? It sounds like you have an existing interest and expertise.

-- E

···

On Jul 6, 2016, at 7:51 AM, Charlie Monroe <charlie@charliemonroe.net> wrote:

* Consider renaming or eliminating ManagedProtoBuffer. "The reason why ManagedProtoBuffer exists is to give the users an extra bit of type safety inside of the closure passed to ManagedBuffer.create(). This closure receives the ManagedBuffer instance and returns the initial value that is stored in the buffer (the header part of the buffer). We are passing the ManagedBuffer as ManagedProtoBuffer to prevent the closure from reading the uninitialized value property. Maybe this extra bit of safety is not worth the API surface complexity." (https://bugs.swift.org/browse/SR-1955 rdar://problem/26012924 <rdar://problem/26012924> rdar://problem/27118532 <rdar://problem/27118532>.")

* withUnsafePointer shouldn't take its argument as inout. (https://bugs.swift.org/browse/SR-1956 rdar://problem/25019862 <rdar://problem/25019862>) Note: "Jordan has objections, see https://bugs.swift.org/browse/SR-1956"

-- E
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jordan Rose) #5

I believe `ObjectIdentifier(self)` prints basically the same way.

Jordan

···

On Jul 6, 2016, at 11:03, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

* Remove unsafeAddressOf. "We are not aware of any real use cases for it. If there are any, it should be renamed to unsafeAddress(of:) to follow the guidelines." (https://bugs.swift.org/browse/SR-1957 rdar://problem/18589289 <>)

Oops, I just responded to this on another thread. Pasting:

It's minor, but I use unsafeAddressOf regularly for writing `description` methods:

    var description: String {
        return "<\(self.dynamicType): \(unsafeAddressOf(self))>{ more info here... }"
    }

I guess this would be covered by some generalized solution for format specifiers in string interpolations, but I gather that won't happen for quite a while...


(Charlie Monroe) #6

As was pointed out to me in the bug report, the preferred way to get a pointer is to use

Unmanaged.passUnretained(obj).toOpaque()

I see a few issues, though (aside from toOpaque() missing in Xcode 8b1, haven't installed b2 yet):

- it is quite a verbose way of something I consider should be trivial - getting an address of an object.
- it requires the caller to deal with retain cycle which I don't think should be explicit for getting an address of an object.

I'd personally leave it in the language as it feels similar to dynamicType(obj) and can be a nice-to-have debugging tool.

The most confusing part about unsafeAddress(of:) is implicit bridging which creates a new instance e.g. in case of String, in order to satisfy the AnyObject requirement. Fortunately, this will get eliminated by SE-0072 and Unmanaged suffered from the same issue, though it required you to specify either Unmanaged<NSString> or Unmanaged<AnyObject>.

···

On Jul 6, 2016, at 8:03 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

* Remove unsafeAddressOf. "We are not aware of any real use cases for it. If there are any, it should be renamed to unsafeAddress(of:) to follow the guidelines." (https://bugs.swift.org/browse/SR-1957 rdar://problem/18589289 <>)

Oops, I just responded to this on another thread. Pasting:

It's minor, but I use unsafeAddressOf regularly for writing `description` methods:

    var description: String {
        return "<\(self.dynamicType): \(unsafeAddressOf(self))>{ more info here... }"
    }

I guess this would be covered by some generalized solution for format specifiers in string interpolations, but I gather that won't happen for quite a while...
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Dave Abrahams) #7

If we remove unsafeAddressOf, we have no way to get the address of an
immutable variable. A mutable variable can be passed inout to a
function taking an UnsafePointer, but you can't add & to an immutable
binding.

That's a loss I'm willing to take. I just wanted to point out exactly
what we will have no way to accomplish if we remove unsafeAddressOf.

···

on Wed Jul 06 2016, Jacob Bandes-Storch <swift-evolution@swift.org> wrote:

* *Remove unsafeAddressOf*. "We are not aware of any real use cases for
it. If there are any, it should be renamed to unsafeAddress(of:) to follow
the guidelines." (https://bugs.swift.org/browse/SR-1957
rdar://problem/18589289)

Oops, I just responded to this on another thread. Pasting:

It's minor, but I use unsafeAddressOf regularly for writing `description`
methods:

    var description: String {
        return "<\(self.dynamicType): \(unsafeAddressOf(self))>{ more info
here... }"
    }

I guess this would be covered by some generalized solution for format
specifiers in string interpolations, but I gather that won't happen for
quite a while...

--
Dave


(Charlie Monroe) #8

* Remove unsafeAddressOf. "We are not aware of any real use cases for it. If there are any, it should be renamed to unsafeAddress(of:) to follow the guidelines." (https://bugs.swift.org/browse/SR-1957 rdar://problem/18589289 <>)

Oops, I just responded to this on another thread. Pasting:

It's minor, but I use unsafeAddressOf regularly for writing `description` methods:

    var description: String {
        return "<\(self.dynamicType): \(unsafeAddressOf(self))>{ more info here... }"
    }

I guess this would be covered by some generalized solution for format specifiers in string interpolations, but I gather that won't happen for quite a while...

I believe `ObjectIdentifier(self)` prints basically the same way.

Jordan

Unfortunately, it doesn't:

print("\(ObjectIdentifier(obj))")

--> ObjectIdentifier(_value: (Opaque Value))

···

On Jul 7, 2016, at 12:46 AM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

On Jul 6, 2016, at 11:03, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Charlie Monroe) #9

* *Remove unsafeAddressOf*. "We are not aware of any real use cases for
it. If there are any, it should be renamed to unsafeAddress(of:) to follow
the guidelines." (https://bugs.swift.org/browse/SR-1957
rdar://problem/18589289)

Oops, I just responded to this on another thread. Pasting:

It's minor, but I use unsafeAddressOf regularly for writing `description`
methods:

   var description: String {
       return "<\(self.dynamicType): \(unsafeAddressOf(self))>{ more info
here... }"
   }

I guess this would be covered by some generalized solution for format
specifiers in string interpolations, but I gather that won't happen for
quite a while...

If we remove unsafeAddressOf, we have no way to get the address of an
immutable variable. A mutable variable can be passed inout to a
function taking an UnsafePointer, but you can't add & to an immutable
binding.

That's a loss I'm willing to take. I just wanted to point out exactly
what we will have no way to accomplish if we remove unsafeAddressOf.

I'm OK with removing it as long as:

- ObjectIdentifier provides a correct description (SR-2014)

- ObjectIdentifer.pointerValue returns just the opaque pointer (i.e. exposes private _value member) since I'm not a big fan of having "ObjectIdentifier" in the logs. There should be an easy way of getting a pointer to an object without using Unmanaged.

- Ideally, the description would include dynamicType of the value + pointer:

ObjectIdentifier(NSObject<0x00101234>)

Which can always be achieved by storing Any.Type within ObjectIdentifier - something I believe can be useful on multiple occasions in the future as well.

I.e. full public API for ObjectIdentifier:

public struct ObjectIdentifier : Hashable, Comparable {
    // Existing:
    public var uintValue: UInt { get }
    public var hashValue: Int { get }
    
    public init(_ x: AnyObject)
    public init(_ x: Any.Type)
    
    // New:
    public var pointerValue: UnsafePointer<Void> { get }
    public var type: Any.Type { get }
}

// New:
extension ObjectIdentifier: CustomStringConvertible {
    public var description: String { get } // return "ObjectIdentifier(\(self.type)<\(self.pointerValue)>)"
}

···

On Jul 8, 2016, at 1:01 AM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:
on Wed Jul 06 2016, Jacob Bandes-Storch <swift-evolution@swift.org> wrote:

--
Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Dave Abrahams) #10

I take it back; we already have no way to do that. unsafeAddressOf,
since it only applies to AnyObject, is totally dispensable.

Today you can do:

  Unmanaged.passUnretained(x).toOpaque()

···

on Thu Jul 07 2016, Dave Abrahams <swift-evolution-m3FHrko0VLzYtjvyW6yDsg@public.gmane.org> wrote:

on Wed Jul 06 2016, Jacob Bandes-Storch <swift-evolution@swift.org> wrote:

* *Remove unsafeAddressOf*. "We are not aware of any real use cases for
it. If there are any, it should be renamed to unsafeAddress(of:) to follow
the guidelines." (https://bugs.swift.org/browse/SR-1957
rdar://problem/18589289)

Oops, I just responded to this on another thread. Pasting:

It's minor, but I use unsafeAddressOf regularly for writing `description`
methods:

    var description: String {
        return "<\(self.dynamicType): \(unsafeAddressOf(self))>{ more info
here... }"
    }

I guess this would be covered by some generalized solution for format
specifiers in string interpolations, but I gather that won't happen for
quite a while...

If we remove unsafeAddressOf, we have no way to get the address of an
immutable variable.

--
Dave


(Dmitri Gribenko) #11

We should absolutely fix that (does not even require a swift-evolution
proposal). This string that it converts to is completely useless.

Dmitri

···

On Wed, Jul 6, 2016 at 9:57 PM, Charlie Monroe via swift-evolution <swift-evolution@swift.org> wrote:

On Jul 7, 2016, at 12:46 AM, Jordan Rose via swift-evolution > <swift-evolution@swift.org> wrote:

On Jul 6, 2016, at 11:03, Jacob Bandes-Storch via swift-evolution > <swift-evolution@swift.org> wrote:

* Remove unsafeAddressOf. "We are not aware of any real use cases for it.
If there are any, it should be renamed to unsafeAddress(of:) to follow the
guidelines." (https://bugs.swift.org/browse/SR-1957 rdar://problem/18589289)

Oops, I just responded to this on another thread. Pasting:

It's minor, but I use unsafeAddressOf regularly for writing `description`
methods:

    var description: String {
        return "<\(self.dynamicType): \(unsafeAddressOf(self))>{ more info
here... }"
    }

I guess this would be covered by some generalized solution for format
specifiers in string interpolations, but I gather that won't happen for
quite a while...

I believe `ObjectIdentifier(self)` prints basically the same way.

Jordan

Unfortunately, it doesn't:

print("\(ObjectIdentifier(obj))")

--> ObjectIdentifier(_value: (Opaque Value))

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Jordan Rose) #12

Filed a starter bug, https://bugs.swift.org/browse/SR-2014.

Jordan

···

On Jul 7, 2016, at 08:58, Dmitri Gribenko <gribozavr@gmail.com> wrote:

On Wed, Jul 6, 2016 at 9:57 PM, Charlie Monroe via swift-evolution > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Jul 7, 2016, at 12:46 AM, Jordan Rose via swift-evolution >> <swift-evolution@swift.org> wrote:

On Jul 6, 2016, at 11:03, Jacob Bandes-Storch via swift-evolution >> <swift-evolution@swift.org> wrote:

* Remove unsafeAddressOf. "We are not aware of any real use cases for it.
If there are any, it should be renamed to unsafeAddress(of:) to follow the
guidelines." (https://bugs.swift.org/browse/SR-1957 rdar://problem/18589289)

Oops, I just responded to this on another thread. Pasting:

It's minor, but I use unsafeAddressOf regularly for writing `description`
methods:

   var description: String {
       return "<\(self.dynamicType): \(unsafeAddressOf(self))>{ more info
here... }"
   }

I guess this would be covered by some generalized solution for format
specifiers in string interpolations, but I gather that won't happen for
quite a while...

I believe `ObjectIdentifier(self)` prints basically the same way.

Jordan

Unfortunately, it doesn't:

print("\(ObjectIdentifier(obj))")

--> ObjectIdentifier(_value: (Opaque Value))

We should absolutely fix that (does not even require a swift-evolution
proposal). This string that it converts to is completely useless.