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

Joe Groff jgroff at apple.com
Wed Dec 16 15:20:47 CST 2015


> On Dec 16, 2015, at 1:11 PM, Kevin Ballard <kevin at sb.org> wrote:
> 
> On Wed, Dec 16, 2015, at 11:58 AM, Joe Groff wrote:
>> 
>>> On Dec 16, 2015, at 11:38 AM, Kevin Ballard via swift-evolution <swift-evolution at swift.org> wrote:
>>> 
>>> withExtendedLifetime(&x) { (ptr: UnsafePointer<Int>) in
>>>   // ...
>>> }
>> 
>> withExtendedLifetime doesn't have this overload. Adding it would essentially be just renaming withUnsafePointer.
> 
> No overload necessary. As I said, it already works today (tested in Swift 2.1). The generic type T is resolved to UnsafePointer<Int>, and so you can pass &x into it just fine because you're passing it to a parameter of type UnsafePointer.

That's interesting emergent behavior, but it's not something we anticipated withUnsafePointer being used for.

>>> # Detailed Solution
>>> 
>>> The functions would be marked as unavailable with a message saying to pass &x directly to the function taking a pointer. If it's feasible to do so, Fix-Its would be introduced for the trivial case of the pointer being used once in the closure as a parameter to a function.
>>> 
>>> The documentation of UnsafePointer and UnsafeMutablePointer would be edited to include a mention of how &x refs can be passed to functions expecting an UnsafePointer or UnsafeMutablePointer. This way anyone new to the language who encounters those types in the wild will be able to easily see how to create one from a variable.
>> 
>> 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.
> 
> Why constrain the magic pointer conversions?

In general, implicit conversions are bad. These particular conversions lead to lots of gross knock-on effects, things like [1] - [2] working by taking the difference of two transient pointers.

> We should discourage people from writing Swift functions that take UnsafePointers, but sometimes it is appropriate (e.g. when wrapping imported C functions, if you need a stable pointer or need to do pointer math, then your function should be taking Unsafe[Mutable]Pointer instead of taking an inout parameter).

If you need a stable pointer internally in your implementation, I don't see a reason to expose that implementation detail to users. You could use withUnsafeMutablePointer(&inoutParameter) internally.

> 
>> Your proposed alternatives all involve essentially reimplementing withUnsafePointer in a different way.
> 
> Well yeah, but without requiring anything in the stdlib. swiftdoc.org lists 36 global Swift functions. 4 of them are unsafe[Mutable]Pointer[s]. That's 11% of the global functions in the stdlib, for functionality that can already be accomplished without any stdlib support and which is relatively rare.

I agree, it's unfortunate that these functions pollute the global namespace. Maybe they should be static methods of Unsafe[Mutable]Pointer instead?

> The way I see it, if the stdlib didn't already have these functions, we wouldn't add them. So why keep them around? All they do is make people think they're necessary.

We added them because they *are* necessary.

-Joe


More information about the swift-evolution mailing list