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

Geordie Jay geojay at gmail.com
Mon May 9 15:58:26 CDT 2016


Thanks for your patient clarification Joe.

My understanding was that type punning == your example with T* -> Void* ->
T* -> T. Assuming it's not, I now imagine you're talking about
reinterpreting the layout of C structs and the like for some horrifically
beautiful optimisation or low-level trick purpose, which sounds nice but is
way beyond my level of understanding or needs.

I'll take your word for it that the example with aliasing pointers is
something that might actually happen, as it stands it just looks like an
unfortunate programmer error, not sure if that was your point (to catch
that kind of thing before it happens).
Joe Groff <jgroff at apple.com> schrieb am Mo., 9. Mai 2016 um 22:48:

>
> > On May 9, 2016, at 1:25 PM, Geordie Jay <geojay at gmail.com> wrote:
> >
> > So what's in it for us as Swift devs?
> >
> > It may be technically undefined behaviour (by that I think you mean
> there's no real knowing what could happen), but it seems to be rampant
> throughout pretty much all the C code I've come in contact with (I'm less
> familiar with C++).
>
> Undefined behavior means that the compiler can optimize as if it couldn't
> happen. For example, in this C code:
>
>         int foo(int *x, float *y) {
>                 *x = 2;
>                 *y = 3.0;
>                 return *x;
>         }
>
> the compiler will likely optimize 'foo' to always return 2, since it's
> allowed to assume its pointer parameters x and y are different types so
> don't alias, If code calls `foo` with aliasing pointers such as `foo(&x,
> (float*)&x)`, it'll break.
>
> > If we lose type information by calling a C API that takes a void
> pointer, how can we hope to retrieve it in any safe way, other than saying
> "we assume with good reason and hope to hell that this is what we say it
> is".
>
> This doesn't change anything in that respect. The aliasing rules in C and
> Swift refer to the type of value that's dynamically stored in memory, not
> the static type of a pointer. It's legal to cast a pointer from T* to void*
> and back to T*, and load a T from the resulting pointer, so long as a T
> value resides in the referenced memory at the time the load occurs.
>
> > And if we can't do that, what advantage does this proposal provide over
> what we already have?
>
> This API gives you a way to legally perform pointer type punning, when you
> do want to reinterpret memory as a different type. In C and C++ the only
> standard way to do so is to `memcpy`.
>
> -Joe
>
> > Joe Groff <jgroff at apple.com> schrieb am Mo., 9. Mai 2016 um 22:16:
> >
> > > On May 9, 2016, at 12:38 PM, Geordie Jay via swift-evolution <
> swift-evolution at swift.org> wrote:
> > >
> > > I read this proposal and I'm a bit unsure what its purpose would be:
> > >
> > > Basically you want to prevent UnsafePointer<XYZ>(UnsafePointer<Void>)
> conversions and/or vice-versa? And you'd achieve this by replacing
> UnsafePointer<Void> with UnsafeBytePointer that has no bound pointer type?
> > >
> > > In one sense the change seems fine to me, but as someone who uses a
> lot of C APIs and a lot of CoreAudio/CoreMIDI in Swift already I can't
> really see what benefit it'd bring. Presumably we'd still want an option of
> converting UnsafeBytePointer to UnsafePointer<SomeActualType> for things
> like C function pointer callback "context"/"userInfo" uses, so it's not
> like we'd be preventing programmer error in that way.
> > >
> > > Call me conservative but to me the current system seems to work as
> well as it can. If anything it's already enough boilerplate going through
> hoops converting an UnsafeMutablePointer<Void> into a [Float] even when I
> know and the C API knows perfectly well what it actually contains... Would
> happily be convinced otherwise about this proposal though, I'm pretty new
> at all this.
> > >
> > > Geordie
> >
> > > On May 9, 2016, at 12:57 PM, Guillaume Lessard via swift-evolution <
> swift-evolution at swift.org> wrote:
> > >
> > > I’m sympathetic to the elimination of UnsafePointer<Void> as general
> shorthand for an arbitrary pointer, but I lose the plot of this very long
> proposal. It seems to me that this increases API surface, yet everything I
> could do before, I could still do; it just involves more typing. What
> exactly does this make better?
> > >
> > > Cheers,
> > > Guillaume Lessard
> >
> > Andy, I think it's worth clarifying the primary purpose of this
> proposal. Our main goal here is to provide a legal means for "type-punning"
> memory access. Like C and C++, it's technically undefined behavior in Swift
> to cast an UnsafePointer<T> to an UnsafePointer<U> of a different type and
> load a value out of memory that's of a different type from what was stored
> there. We don't take much advantage of this yet in Swift's optimizer, since
> we don't have good alternative API. UnsafeBytePointer seeks to fill this
> gap by providing a type that can safely do type-punned loads and stores.
> >
> > -Joe
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160509/7718cf6d/attachment.html>


More information about the swift-evolution mailing list