Proposal: [stdlib] Remove withUnsafe[Mutable]Pointer[s]()


(Rainer Brockerhoff) #1

I just tested this; I had two nested withUnsafeMutablePointer() calls,
and removing them works perfectly. For context, this is what I have now:
(slightly simplified)

func GetCodeSignatureForURL(url: NSURL) -> NSDictionary? {
  var result: NSDictionary? = nil
  var code: SecStaticCode? = nil
  let err: OSStatus = SecStaticCodeCreateWithPath(url,
SecCSFlags.DefaultFlags, &code)
  if err == OSStatus(noErr) && code != nil {
    var dict: CFDictionary? = nil
    let err = SecCodeCopySigningInformation(code!, SecCSFlags(rawValue:
kSecCSSigningInformation), &dict)
    result = err == OSStatus(noErr) ? dict as NSDictionary? : nil
  }
  return result
}

Not sure if this usage is "well-behaved" as Joe says, since I get `code`
in one call and then use it (once) later.

For such cases I'm certainly +1 on the proposal.

···

On 12/16/15 18:22, swift-evolution-request@swift.org wrote:

Date: Wed, 16 Dec 2015 11:58:41 -0800
From: Joe Groff <jgroff@apple.com>
To: Kevin Ballard <kevin@sb.org>
Cc: swift-evolution@swift.org
Subject: Re: [swift-evolution] Proposal: [stdlib] Remove
  withUnsafe[Mutable]Pointer[s]()
Message-ID: <07AA6EB4-F053-4A17-9746-4A04C18D87B7@apple.com>

>
> Remove the functions from the stdlib. The Swift Book should also be updated to talk about passing an &x ref to a function that takes an UnsafePointer or UnsafeMutablePointer (but of course changes to the book are not covered by the open-source project). Most uses of these functions can probably be replaced with a &x ref directly.>

I'm against removing the functionality. The magic pointer conversions were only ever intended to make interop with well-behaved C functions easier; it was in my mind that we would eventually constrain the magic pointer conversions to only apply to imported APIs. withUnsafePointer is necessary more often than you think, since the current semantics of the conversion only keep the pointer valid for one call—you can't call a conversion constructor or otherwise touch the pointer in between. We should fix that, but it'll still be necessary to persist a pointer across multiple C calls that expect pointer identity to be maintained. Your proposed alternatives all involve essentially reimplementing withUnsafePointer in a different way.

--
Rainer Brockerhoff <rainer@brockerhoff.net>
Belo Horizonte, Brazil
"In the affairs of others even fools are wise
In their own business even sages err."
http://brockerhoff.net/blog/


(Joe Groff) #2

That's fine. These APIs only care about the value being referenced, not the exact identity of the pointer.

-Joe

···

On Dec 16, 2015, at 12:53 PM, Rainer Brockerhoff <rainer@brockerhoff.net> wrote:

On 12/16/15 18:22, swift-evolution-request@swift.org wrote:

Date: Wed, 16 Dec 2015 11:58:41 -0800
From: Joe Groff <jgroff@apple.com>
To: Kevin Ballard <kevin@sb.org>
Cc: swift-evolution@swift.org
Subject: Re: [swift-evolution] Proposal: [stdlib] Remove
  withUnsafe[Mutable]Pointer[s]()
Message-ID: <07AA6EB4-F053-4A17-9746-4A04C18D87B7@apple.com>

Remove the functions from the stdlib. The Swift Book should also be updated to talk about passing an &x ref to a function that takes an UnsafePointer or UnsafeMutablePointer (but of course changes to the book are not covered by the open-source project). Most uses of these functions can probably be replaced with a &x ref directly.>

I'm against removing the functionality. The magic pointer conversions were only ever intended to make interop with well-behaved C functions easier; it was in my mind that we would eventually constrain the magic pointer conversions to only apply to imported APIs. withUnsafePointer is necessary more often than you think, since the current semantics of the conversion only keep the pointer valid for one call—you can't call a conversion constructor or otherwise touch the pointer in between. We should fix that, but it'll still be necessary to persist a pointer across multiple C calls that expect pointer identity to be maintained. Your proposed alternatives all involve essentially reimplementing withUnsafePointer in a different way.

I just tested this; I had two nested withUnsafeMutablePointer() calls,
and removing them works perfectly. For context, this is what I have now:
(slightly simplified)

func GetCodeSignatureForURL(url: NSURL) -> NSDictionary? {
  var result: NSDictionary? = nil
  var code: SecStaticCode? = nil
  let err: OSStatus = SecStaticCodeCreateWithPath(url,
SecCSFlags.DefaultFlags, &code)
  if err == OSStatus(noErr) && code != nil {
    var dict: CFDictionary? = nil
    let err = SecCodeCopySigningInformation(code!, SecCSFlags(rawValue:
kSecCSSigningInformation), &dict)
    result = err == OSStatus(noErr) ? dict as NSDictionary? : nil
  }
  return result
}

Not sure if this usage is "well-behaved" as Joe says, since I get `code`
in one call and then use it (once) later.