The perils of pinning
The perils of pinning
Posted Sep 15, 2022 20:23 UTC (Thu) by mb (subscriber, #50428)In reply to: The perils of pinning by fw
Parent article: The perils of pinning
No. Not really.
The only difference is that in Rust the "the old object is still around" is zero time.
Everything else is the same.
Rust can't rip out memory from your machine. Therefore it also technically copies.
The difference between a copy and a move is that the lifetime of the old object is terminated immediately and not at some later point. And based on that the compiler might be able to apply some optimizations to omit the copy altogether.
And if you copy a self referential object, it's by definition not self referential after copy. It references another object (the original one!). Not self.
Posted Sep 16, 2022 1:59 UTC (Fri)
by JoeBuck (subscriber, #2330)
[Link] (3 responses)
Posted Sep 16, 2022 18:10 UTC (Fri)
by tialaramex (subscriber, #21167)
[Link] (2 responses)
Rust's Clone trait, which is what happens if you clone() something that admits it can be cloned, is a function you can implement. For example my Multiplicity https://docs.rs/misfortunate/1.0.0/misfortunate/struct.Mu... wrapper type claims to be Clone, despite the fact all it asks of your wrapped type T is that it should be Default. Multiplicity's clone() implementation just makes a Default::default() of your type, which is type correct but presumably not what you wanted. (The name is a reference to the 1996 Andie MacDowell comedy in which Michael Keaton clones himself repeatedly and gradually the clones deteriorate in quality)
But you deliberately can't intervene in the simple memcpy() behaviour when the compiler decides to move your object in memory. The Rust compiler reserves the rights to do this more often than you expect, or less often, and in different places, as it sees fit. Pinning stops it from doing that, at some potential cost in performance.
Posted Sep 22, 2022 6:44 UTC (Thu)
by Homer512 (subscriber, #85295)
[Link] (1 responses)
If the compiler already has facilities to detect when an object should not be moved, why is it so hard to give it facilities to invoke a custom function for the move instead?
Posted Sep 27, 2022 9:27 UTC (Tue)
by farnz (subscriber, #17727)
[Link]
It's hard because the consequence of adding a "move fix-up" function is to break the mental model people have of Rust code.
In today's world, the maximum cost of a move in Rust (or a copy for things that impl Copy) is a memory copy of the object. The cost of a move is thus predictable.
If Rust adds a "move fix-up" function of some form, that predictability goes away - you now depend on the implementation of the move function being high-quality. C++ goes this route, of having hidden fix-up functions (operator=, move and copy constructors), and thus provides an illustration of the benefits of that approach (where all developers are skilled) and of the costs (where some developers are unskilled and don't realise that they're invoking a lot of code doing a move).
Actually implementing the changed semantics in the compiler would be trivial - it's the human cost of learning how the new semantics work that's non-trivial.
Posted Sep 17, 2022 14:01 UTC (Sat)
by jezuch (subscriber, #52988)
[Link] (1 responses)
Posted Sep 18, 2022 14:57 UTC (Sun)
by matthias (subscriber, #94967)
[Link]
And for correctness of self referential objects, you have to assume that the object might be physically moved if it is logically moved. Also, for unpinned and unaliased objects, the compiler is free to move it around for code optimization, even without a logical move.
Posted Sep 18, 2022 17:40 UTC (Sun)
by fw (subscriber, #26023)
[Link]
The perils of pinning
The perils of pinning
The perils of pinning
The perils of pinning
The perils of pinning
The perils of pinning
- the object is moved from the stack to the heap
- the object is moved between different allocations on the heap
- the object is moved to a function parameter (if the function is not inlined, then the object has to be moved to the place where the function expect its input, for inlined funtions, the move will usually be avoided)
The perils of pinning
Rust can't rip out memory from your machine. Therefore it also technically copies.
Aren't Rust semantics such that the moved-from object becomes invalid as part of the move? What happens in a concrete computer implementation does not really matter for correctness if the abstract machine behaves differently. If the object is gone in the abstract machine, compilers can and will eventually optimize based on the assumption that accesses to it will not happen during the execution of the program.