I've read @Andrew_Trick's excellent explanation about binding etc here but I'm still not entirely sure about the following.
Are there any situations where, assuming you've allocated memory to an UnsafeRawMutablePointer
, you don't have to bind it to some type?
AFAICS, one such case would be if the data of that pointer would only ever be accessed via load(fromByteOffset: as:)
and storeBytes(of: toByteOffset: as:)
. Correct?
I guess it depends on what exactly the following means (from the storeBytes
documentation):
If the memory is bound to a type
U
that is layout compatible withT
, then it contains a value of typeU
.
(There's no explicit mention of whether the memory must be bound to some type or if it's OK for it to not be bound to any type.)
And, a question about the following from the documentation for store
and load
:
The memory at this pointer plus
offset
must be properly aligned for accessingT
What exactly does this mean? I guess it just means that offset
should point at the first byte of the value. Or does it mean that the address must be a multiple of MemoryLayout<T>.alignment
, meaning the following example is incorrect or unsafe?
func example() {
let ptr = UnsafeMutableRawPointer.allocate(byteCount: 9, alignment: 16)
ptr.storeBytes(of: UInt8(123), toByteOffset: 0, as: UInt8.self)
ptr.storeBytes(of: Double(4.56), toByteOffset: 1, as: Double.self)
let a = ptr.load(fromByteOffset: 0, as: UInt8.self)
let b = ptr.load(fromByteOffset: 1, as: Double.self)
print(a) // 123
print(b) // 4.56
ptr.deallocate()
}
example()
In this example there is no binding, and the Double
value is stored at an address which is not a multiple of MemoryLayout<Double>.alignment
, and I assume that that's OK/correct/safe.
Please correct me if I'm wrong.