[swift-evolution] Proposal: Extend the &x -> UnsafePointer behavior to work with immutable values

Joe Groff jgroff at apple.com
Wed Dec 16 15:29:56 CST 2015


> On Dec 16, 2015, at 1:18 PM, Kevin Ballard <kevin at sb.org> wrote:
> 
> On Wed, Dec 16, 2015, at 11:54 AM, Joe Groff wrote:
>> 
>>> On Dec 16, 2015, at 11:44 AM, Kevin Ballard via swift-evolution <swift-evolution at swift.org> wrote:
>>> 
>>> # Introduction
>>> 
>>> Swift allows you to pass a &x ref to a function taking Unsafe[Mutable]Pointer, as long as x is mutable.
>>> 
>>> # Problem
>>> 
>>> There's no way to pass an immutable UnsafePointer that points to immutable data. Any such immutable data has to be copied into a mutable variable before the &x ref works.
>> 
>> This isn't strictly true; you can pass [x].
> 
> Really? I had no idea you could pass arrays to functions expecting pointers. I assume it still creates an intermediate Array object though (and copies the value to the heap).

True. Nadav's team is in the process of implementing stack promotion for literal arrays, which should cut the cost down; this is also something SILGen could reasonably peephole (and similarly, passing a string to a C function should just pass a static string and not bridge through String).

> 
> I know you can pass a String to a function expecting UnsafePointer<Int8/UInt8>. And now I know about Array. Are there any other types that can be passed like this?

I think that's it—String, Array, and vars are the things that are implicitly bridged to C pointers. 

-Joe

> 
>>> # Solution
>>> 
>>> Allow for using &x with immutable values if and only if the reference is passed as a parameter to a function expecting UnsafePointer
>> 
>> Seems reasonable. As I mentioned on swift-dev, '&x' in Swift indicates "this call mutates x with inout semantics", not the C sense of "I'm passing a pointer", so doing the conversion without an '&' seems more Swift-ish to me. The semantics of the implicit const pointer conversion also only allow the C call to treat the parameter as if it were an immutable value operand; any capture of or mutation through the variable is UB.
> 
> Fair enough. I'm still leaning towards keeping the &, because it feels a little odd to require foo(&x) for UnsafeMutablePointer and allow foo(x) for UnsafePointer, but I admit that may just be because &x looks like the C address-of operator. One benefit of dropping the & is it then becomes reasonable to say foo(42), whereas foo(&42) feels a little odd (but maybe no more odd than C's &(int){42}).
> 
> -Kevin Ballard



More information about the swift-evolution mailing list