class Stream
{
var stream:z_stream
}
var stream:Stream
mutating
func foo1()
{
withUnsafeMutablePointer(to: &self.stream.stream)
{
(storage:UnsafeMutablePointer<z_stream>) in
bar1(storage)
}
}
mutating
func foo2()
{
withUnsafeMutablePointer(to: &self.stream.stream)
{
(storage:UnsafeMutablePointer<z_stream>) in
bar2(storage)
}
do I have any guarantees about the location of storage between foo1 and foo2? the reason I’m asking is because zlib for some reason stores internally a pointer to something in the z_stream struct and it checks the consistency of this pointer in every library method. i already figured out a long time ago the z_stream has to be wrapped in a reference type to keep it from getting copied, and the class wrapper seems to fix everything for now, but is this defined behavior, especially since the z_stream itself is still a (C) struct?
I believe the inout-to-pointer conversion for a final stored class property gives you a consistent address each time, but otherwise it's not guaranteed. @Joe_Groff, @John_McCall, confirm/deny?
An access through a normal property read or write, inout-to-pointer call, or inside the confines of a withUnsafePointer/Bytes call. Even if you get the same pointer, code that reads or writes through the pointer outside of withUnsafe* may cause unpredictable behavior:
final class C { var x: Int }
let x = C()
var p: UnsafeRawPointer?
withUnsafeBytes(of: &x.x) {
p = $0.startAddress
print(p.load(as: Int.self)) // ok
}
print(p.load(as: Int.self)) // not ok
withUnsafeBytes(of: &x.x) {
print(p.load(as: Int.self)) // probably ok
}