[swift-dev] [RFC] UnsafeBytePointer API for In-Memory Layout

Andrew Trick atrick at apple.com
Thu May 12 20:34:02 CDT 2016

> On May 12, 2016, at 9:27 AM, Jordan Rose <jordan_rose at apple.com> wrote:
> On the model itself:

Responding to your feedback on the model (thanks!). 
https://github.com/atrick/swift/blob/type-safe-mem-docs/docs/TypeSafeMemory.rst <https://github.com/atrick/swift/blob/type-safe-mem-docs/docs/TypeSafeMemory.rst>
With just one follow up question at the bottom of this email…

> - "thin function, C function, and block function types” <-- block functions are not layout-compatible with C functions, and they are layout-compatible with AnyObject. (I mean, they’re both pointers at the moment, but so are non-weak object references.)

   - pointer types (e.g. ``OpaquePointer``, ``UnsafePointer``)
-  - thin function, C function, and block function types
+  - block function types and ``AnyObject``
+  - thin function and C function types
   - imported C types that have the same layout in C

> - "nonresilient structs” <-- nitpick: the term “nonresilient” is not defined here, and isn’t a formal term in the Library Evolution doc. I guess I would actually prefer “fragile” if you needed a generic term across structs and enums, but either way you should put a small definition somewhere in this doc.

   - imported C types that have the same layout in C
-  - nonresilient structs with one stored property and their stored
+  - fragile structs with one stored property and their stored
     property type
-  - nonresilient enums with one case and their payload type
+  - fragile enums with one case and their payload type
 .. note::
-   `Library Evolution Support in Swift`__
+   "Fragile" enums and structs have strict layout rules that ensure
+   binary compatibility. `Library Evolution Support in Swift`__
    explains the impact of resilience on object layout.

> - "homogeneous tuples, fixed-sized array storage, and homogeneous nonresilient structs in which the element type has no spare bits (structs may be bit packed).” <-- I would leave the structs out of this, even if it’s true. Also, Swift doesn’t have fixed-size arrays at the moment, right?

Hmm, I think we want to say that raw allocated memory, arrays, homogeneous tuples and structs are layout compatible with 'strideof'. I'll leave out structs for now and this can be hashed out in ABI specs. I want to avoid naming specific API's and I think it's ok to be a bit vague in this (non-ABI) document as long as the intent is obvious:

  - contiguous array storage and homogeneous tuples which 
    have the same number and type of elements.

> - "In particular, they apply to access that originates from stored property getter and setters, reading from and assigning into inout variables, and reading or assigning subscripts (including the Unsafe[Mutable]Pointer pointee property and subscripts).” I’m unhappy with inout variables being called out specially here. An inout variable should be exactly like a local variable that happens to be stack-allocated, rather than just in registers. Closure captures probably figure in here too.

Agreed. I'm not sure what I was thinking.

> - "unsafeBitCast is valid for pointer to integer conversions” <-- we have better APIs to do this now ('init(bitPattern:)’ in both directions).

+``unsafeBitCast`` should generally be avoided on pointer types,
+particularly class types. For pointer to integer conversions,
+``bitPattern`` initializers are available in both
+directions. ``unsafeBitCast`` may be used to convert between
+nondereferenceable pointer types, but as with any conversion to and
+from opaque pointers, this presents an opportunity for type punning
+when converting back to a dereferenceable pointer type.

> - "It is also used internally to convert between nondereferenceable pointer types, which avoids the need to add builtin conversions for all combinations of pointer types.” <-- I’d be happy to get rid of this and just go through Builtin.RawPointer when necessary.

...I do like to get feedback that eliminating unsafeBitCast is a good thing. I think it should only be needed for genuine reinterpretation of the bits as opposed working around the type system. I'd like to see only a tiny handful of occurrences in stdlib. I have a branch where I've cleaned up many unsafeBitCasts, which never got checked in, so I can spend some time on that again after UnsafePointer changes land. Then maybe we should prohibit it from being called on certain pointer types. For starters AnyObject, UnsafePointer, and UnsafeBytePointer.

> - On the flip side, I think we do need to preserve the ability to reference-cast in order to send Objective-C messages, at least for now. I don’t know how I want to expose that to users, though. (In general it’s probably worth seeing how unsafeBitCast is used in the wild and what we’d recommend instead.)

Does ``X as Y`` fail for some reason? We have unchecked versions of ``X as Y`` for performance reasons: ``unsafeDowncast`` and ``_unsafeReferenceCast``.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160512/5c9b7d81/attachment.html>

More information about the swift-dev mailing list