On 10/11/24 09:25, Manu wrote:
> I don't see how elevating this declaration to a move-constructor
> actually changes the semantics at all... I don't think it does? I think
> this function ALREADY IS A MOVE CONSTRUCTOR (at least; it's an rvalue-
> constructor, which is the same thing from a semantic perspective); it's
> just working with an inefficient calling convention.
> Move semantics as proposed simply improve this code, no?
DIP1040 suggests to pass the argument implicitly by reference and to not
call the destructor on it.
As I mentioned in my DConf talk, this can lead to accidental memory
leaks. Particularly if it is existing code that previously assumed the
destructor will run.
I feel like we resolved this; we agreed that the no destructor call in 1040 was a mistake. If the callee decides to do anything invasive with its argument, like stealing it's allocations in a move operation, it must return it to a destructible state. The memory's lifetime in the calling code would continue, and call the destructor as usual.
I felt confident we agreed on that requirement and it resolved the issues you illustrated?
Another point where it will differ is automatic generation of move
constructors and move `opAssign`. I think now it has to be done manually
or you get copies.
Finally, for some reason, at the moment you cannot have both `this(ref
S)` and `this(S)`. But `opAssign(ref S)` and `opAssign(S)` works. This
moves around values in memory a bit more often though. A semantic move
may just pass a reference further down the call stack.
Yes, pretty much the entire point of this work is enabled passing the point "further down the line", copying at each function boundary is precisely the problem to be solved.
(IIRC non-POD
struct types are always passed by `ref` in the ABI.)
Yes, essentially, we're just acknowledging in the language semantics what is already true in the ABI.