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 with T , then it contains a value of type U .
(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 accessing T
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.