/// Creates a new raw pointer from the given address, specified as a bit
/// pattern.
///
/// - Parameter bitPattern: A bit pattern to use for the address of the new
/// raw pointer. If `bitPattern` is zero, the result is `nil`.
public init?(bitPattern: Int)
I understand exactly what it says, but it fails to explain why it has to be a failable initializer, and why it should return nil when bitPattern is zero.
I mean, we can still successfully compile and run eg:
let p = UnsafeMutableRawPointer.init(bitPattern: 1)! - 1
print(p) // 0x0000000000000000
This is of course unsafe, just like a lot of other things you can do with unsafe pointers (hence the naming), so what is this initializer trying to protect me from?
It's perfectly happy to let me use the bitPattern -1, resulting in the address being UInt64.max:
let p = UnsafeMutableRawPointer.init(bitPattern: -1)!
print(p) // 0xffffffffffffffff
Is it failable and nil for the zero bit pattern because of something that has to do with NULL in C interop or something?
Remember that nilis the representation of a null pointer, but at the same time people pass null pointers through uintptr_t fields sometimes. So the initializer isn't trying to protect you; it's just doing the same thing that C does when you say (void *)bitPattern. (If I wanted to be more explicit, I could say (void * _Nullable)bitPattern. ;-) )
As you discovered, you can form a non-Optional UnsafePointer with an address of 0 if you really try. However, you're likely to run afoul of optimizations that assume things about optional and non-optional pointers if you do, so I don't recommend it.
Thanks, a related question: I think I read somewhere that bindMemory is zero overhead (because it's just info for the compiler) but I guess that force unwrapping an optional UnsafeMutableRawPointer might induce a performance overhead, as in eg
assuming it is not possible for the compiler to know whether (the top version's) rawCellData is nil or not?
(This is from a single swift file that contains a very low-level implementation of an algorithm/data structure, built using only private top level functions that manipulates some data pointed to by the private top level UnsafeMutableRawPointerrawCellData.
There are also a couple of module-internal functions in that file, forming its "interface", eg: