Something like `unsafelyInitializedBytes<T>(as _: T.Type)` -> T

There doesn't seem to be a way to initialize a value via a pointer to its bytes without first having to "normally" initialize that value, ie:

// var x: T // <-- This will not work, but is what I want, ideally I'd even want it to be `let x: T`.
var x: T = someValueT // <-- I have to unnecessarily initialize `a` before being able to initialize its bytes via a pointer.
withUnsafeMutableBytes(of: &x) {
  ... `a` will be initialized here ...
}

Note also that apart from the fact that someValueT will be immediately overwritten, there might not even be a someValueT available at this place in the code, ie what if I only have an UnsafeRawBufferPointer to the bytes of a T here?

What I'm looking for is something analogous to the existing

Array.init(unsafeUninitializedCapacity: initializingWith: )

but for any type T (not just arrays), ie:

let x = unsafelyInitializedBytes(as: T.self) { ... }

or

let x: T = unsafelyInitializedBytes() { ... }

If there's nothing like this in Swift today, would it be a reasonable thing to add?

(Example use case: important low level building block when implementing eg a library for efficient decoding from a stream of bytes.)

Hmm, now I realize that I could probably just use load from a raw pointer ...

1 Like

Yep

For trivial types the compiler will also optimise this away for you. For example, here is a Godbolt link showing a double-initialization being optimised away.

This optimisation will fail if the compiler cannot prove that the original initialization has no side effects. This means that if there are calls to non-inlinable functions defined outside the module (such as some of the backing functions on Array) the optimisation can fail. For trivial types, though (the only kind of type safe to initialize by bitwise copying) the optimisation should never fail if the type was defined in your module.

1 Like

The poblem with load is (if I remember correctly) that it requires the memory to be properly aligned for the target type. It has been suggested to provide an unaligned version as well, e.g. here: Built-in unaligned loads.

1 Like

Right, this makes it unusable for my concrete use case. I guess I'll have to use memcpy and double-initializing (which gets optimized away).

You may also be interested in the thread Best practice for parsing heterogeneous types from Data (in Swift 5).

1 Like