[swift-evolution] Swift *less* safe than C for imported API that uses opaque struct pointers

Jordan Rose jordan_rose at apple.com
Thu Jun 23 11:17:18 CDT 2016


> On Jun 22, 2016, at 12:58, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
> 
>> 
>> On Jun 22, 2016, at 11:20 AM, Timothy J. Wood via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> 
>> Currently, APIs that get imported with COpaquePointer make Swift *less* safe than C. Fixing this seems like a breaking change, since it would change the meaning of existing code that uses COpaquePointer. 
>> 
>> As a motivating example consider:
>> 
>> import Darwin
>> 
>> var state = copyfile_state_alloc()
>> print("state = \(state.dynamicType) \(state)")
>> 
>> let acl = acl_init(1)
>> print("acl = \(acl.dynamicType) \(acl)")
>> 
>> state = acl
>> print("state = \(state.dynamicType) \(state)")
>> 
>> I’m just using these types since they use opaque structs and are easy to create in this sample, but this pattern is fairly common in other C APIs that try to encapsulate their implementation.
>> 
>> This compiles and builds, silently accepting the bogus code:
>> 
>> DEVELOPER_DIR=/Applications/Xcode-8.0b1.app/Contents/Developer  swift c-unsafety.swift
>> state = Optional<OpaquePointer> Optional(0x00007f9db481b3d0)
>> acl = Optional<OpaquePointer> Optional(0x00007f9db2944c00)
>> state = Optional<OpaquePointer> Optional(0x00007f9db2944c00)
>> 
>> The equivalent C version:
>> 
>> copyfile_state_t state = state = copyfile_state_alloc();
>> acl_t acl = acl_init(1);
>> state = acl;
>> 
>> produces a warning:
>> 
>> c-unsafety.c:10:8: warning: incompatible pointer types assigning to 'copyfile_state_t' (aka 'struct _copyfile_state *') from 'acl_t' (aka 'struct _acl *')
>> 
>> 
>> Would it be feasible to import these sorts of pointers in a safe(r) way by making COpaquePointer generic and faking up a struct tag type? So, these might get imported with something equivalent to:
>> 
>> struct _acl {}
>> typealias acl_t = COpaquePointer<_acl>
> 
> We should be able to synthesize opaque types as structs with inaccessible initializers, and use the existing UnsafePointer types. That would work better in situations where you have some modules that can see the implementation of '_acl', and some that can’t.

Right. The concern we’ve had here is that you’ll start off with an opaque struct and then import something else that does have the definition. I think this only comes up in the REPL, though, and maybe it’s rare enough that we could just ignore it or disallow using the type as a value in that case.

Jordan

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160623/6da8c535/attachment.html>


More information about the swift-evolution mailing list