[swift-evolution] [Review] SE-0107: UnsafeRawPointer API (binding memory to type)

Andrew Trick atrick at apple.com
Wed Jul 6 17:33:18 CDT 2016


> On Jul 4, 2016, at 7:52 PM, Jacob Bandes-Storch <jtbandes at gmail.com> wrote:
> 
> This is the first version of this proposal which I've had time to read. I like it a lot overall. If I have some more time, I may try pulling the branch and writing some code with it to see how it feels. (If we could get a toolchain built from the branch, that might help others review it.)

The latest UnsafeRawPointer definition is on this branch:
https://github.com/atrick/swift/tree/rawptr

I plan to update it with the latest round of feedback soonish and send out a PR.
Unfortunately, the type system/stdlib changes are not on that branch, so you won't get any implicit conversions.

> Here are a handful of minor comments:
> 
> - Naming: "bindMemory(to:capacity:)", being "verb-ish", seems incongruous with "assumingMemoryBound(to:)" and "withMemoryRebound(to:capacity:_:)". How about "bindingMemory(to:capacity:)” ?

DaveA is right, "bind" is active, "assumingMemoryBound" is passive. "withMemoryRebound" temporarily rebinds the type and implies that the closure may mutate state.

> - Would it be possible for "+(UnsafeRawPointer, Int) -> UnsafeRawPointer" to accept any Integer or FixedWidthInteger, rather than only Int?

I'm not sure what all the tradeoffs are, but I don't think we want to index memory with non-Int sized integers. I think the user should be required to convert, which may trap.

> - Why allow/encourage multiple calls to bindMemory on the same RawPointer? These APIs do a good job of making aliasing explicit by introducing data dependencies between pointers (you can only use a typed pointer after obtaining it from a raw pointer, and you can recover the raw pointer for later use by deinitializing the typed pointer). So, I would think the guidelines should prefer bindMemory to be used only once on a particular RawPointer value.

DaveA's answer was good. "bindMemory" is not really encouraged by the API. It's just mentioned a lot in the proposal because the semantics are interesting.

"bindMemory" is important because it's the only safe way to reinterpret in-memory values. So you need to use it to pass a UInt8 array off as a CChar, and so forth, which is actually quite common.

It is certainly encouraged more than unsafeBitCast(ptr, to: ...) because `bindMemory` is actually safe as long as you know the layout of the types and don't reuse your old typed pointers.

> And minor notes about the proposal itself:
> 
> - strideof(Int.self) is used in most examples, but sizeof(Int.self) appears in one of them (the "normalLifetime()" example).

That example is actually allocating memory for a single value. Should it be changed to `strideof`? If so, then what's the point of `sizeof`?

> - I think there must be a mistake in this example, because pA is already bound and bindMemory was only defined for untyped RawPointers:
> 
>     func testInitAB() {
>       // Get a raw pointer to (A, B).
>       let p = initAB()
> 
>       let pA = p.bindMemory(to: A.self, capacity: 1)
>       printA(pA)
> 
>       printB((pA + 1).bindMemory(to: B.self, capacity: 1))   //<<< should this be (p+1) rather than (pA+1)?
>     }

Thanks. That was supposed to be cast to raw pointer like the other examples:

  // Knowing the `B` has the same alignment as `A`...
  printB(UnsafeRawPointer(pA + 1).bindMemory(to: B.self, capacity: 1))

-Andy

> 
> Jacob
> 
> On Mon, Jul 4, 2016 at 3:32 PM, Andrew Trick via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
>> On Jun 28, 2016, at 11:05 PM, Chris Lattner <clattner at apple.com <mailto:clattner at apple.com>> wrote:
>> 
>> Hello Swift community,
>> 
>> The review of “SE-0107: UnsafeRawPointer API” begins now and runs through July 4, 2016. The proposal is available here:
>> 
>> 	https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md <https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md>
> 
> 
> I've revised the proposal again based on extremely helpful feedback from DaveA and Jordan.
> 
> This revision expands on the concept of formally binding the memory type that I was recently working on with Dmitri. Now we can clearly define pre and post conditions on memory operations and pointer casts that can be used to prove the type safety. The model is now simpler, more complete, and easy to reason about locally. This will help developers reason about correctness and make it easy to implement a sanitizer that verifies the type safety of UnsafePointer operations.
> 
> Adding safety to pointer "casts" made it possible for me to actually simplify the allocation and initialization APIs. I think both camps, convenience and safety, will be happy.
> 
> You can see what changed in this pull request:
> https://github.com/apple/swift-evolution/pull/408 <https://github.com/apple/swift-evolution/pull/408>
> 
> Brief summary:
> 
> - Memory is dynamically bound to a single type.
> 
> - All typed access to memory, whether via a typed pointer or regular
>   language construct, must be consistent with the memory's bound type
>   (the access type must be related to the bound type). Typed access
>   includes initialization, assignment, or deinitialization via a typed
>   pointer.
> 
> - Memory remains bound after being deinitialized.
> 
> - Memory is implicitly bound or rebound to a type by initializing it
>   via a raw pointer.
> 
> - A separate API now exists for explicity binding or rebinding memory
>   to a type. This allows binding to be decoupled from initialization
>   for convenience and efficiency. It also supports safe
>   interoperability between APIs that used different, but layout
>   compatible types.
> 
> - Using an API that accesses memory as a different type can now be
>   accomplished by rebinding the memory. This effectively changes the
>   type of any initialized values in memory. The compiler is still
>   permitted to assume strict aliasing for accesses on either side of
>   the operation that rebinds memory.
> 
> Andy
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160706/6366f230/attachment.html>


More information about the swift-evolution mailing list