|
|
|
|
|
by steveklabnik
2684 days ago
|
|
It's not theoretical, it's practical. Here's some code with a self-referential struct: https://play.rust-lang.org/?version=stable&mode=debug&editio... Here, we have a self-referential struct. If you run this, you may get different numbers than me, but [src/main.rs:17] &f = Foo {
x: 5,
p: 0x00007ffcbbba41c0
}
Here, p points to x. It's all good. The address of f is [src/main.rs:19] &f as *const Foo = 0x00007ffcbbba41b8
We move f into oh_no. Its address changes: [src/main.rs:25] &f as *const Foo = 0x00007ffcbbba3f28
... but p does not: [src/main.rs:26] &f = Foo {
x: 5,
p: 0x00007ffcbbba41c0
}
Any access of p is now a use-after-free.Does that make sense? |
|
So to make this work, references would need to be re-written when a move/copy occurs.
I can still see having an easy way to construct self-referential structs being a useful thing, even if the compiler prevents you from moving them. Maybe with a smart clone() method that can update references correctly.
However, I am a little confused about this specific example. I don't understand why oh_no() taking ownership causes f to be copied to a new location. Shouldn't it remain in the same place on the stack? I feel like I'm missing something.