D's equivalent to C++'s std::move?

Ola Fosheim Grøstad via Digitalmars-d digitalmars-d at puremagic.com
Sat Feb 13 11:25:37 PST 2016


On Saturday, 13 February 2016 at 17:47:54 UTC, Lars T. 
Kyllingstad wrote:
> Not knowing anything about the libraries you write, it's hard 
> to argue with that.  But I agree that given that you are in 
> control of all the code AND can make the move ctor/assignment 
> available for inlining (AND are an experienced programmer),

C++ does indeed put the burden on the library programmer and is 
not a good language for "non-professional" use. But it is 
flexible by providing the mechanisms in the type system rather 
than an opinionated solution. (Of course, parts of the C++ 
standard library is opinionated.)

> cannot be inlined.  Then, you are looking at multiple levels of 
> function calls and you are also at the mercy of whoever wrote 
> their move code.

Well, I primarily use move semantics for ownership, like owning 
resources in the GPU, files system, memory etc. So it usually is 
1 or 2 levels.


> Here, you have unnecessary construction of C's members in the 
> constructor which may or may not be optimised away before the 
> assignment.

Well, doing a swap would break the expectations for assignment...

>  Furthermore, you have an unnecessary number of moves in the 
> assignment operator -- plus the potential drawbacks of deferred 
> release of the resource.

I don't understand what you mean by unnecessary moves? 
std::move/std::forward are just type casting so they don't result 
in code...

> I'm not sure what you mean by "has move semantics" here.  It 
> does not have C++'s move semantics, no, but I would say D has 
> its own move semantics.  It has a move() function that 
> transfers raw state between objects, and D structs are supposed 
> to be designed so they are movable by means of raw bit 
> transfer, allowing the compiler and GC to move them around as 
> it sees fit.  But maybe I'm missing something?

Well, but that is like saying that C++03 also had move semantics. 
There is nothing special about D's move(), it's just a library 
function?

>> No? With D's std.move() the resource can be destroyed or get 
>> into an inconsistent state if the caller does it wrong?
>
> I guess this is what I don't understand.  How and when does 
> that happen?

The std.move() actually does a copy, then copy the init value to 
the original. If something happens that prevents the value from 
being preserved the object will be destroyed by the destructors. 
I.e. an exception.

And worse, if you have back pointers to it, it will end up being 
inconsistent. There is no way the type system can prevent back 
pointers without preventing D from being usable as a language. 
Since you no longer have the original object... shit can happen. 
In C++ you can set a mutex in the object and fix things because 
you have the full object. So if someone tries to follow the back 
pointer the mutex will block. You can probably come up with many 
other scenarios. "postblit" does not fix this (not a very elegant 
solution IMO).

So, C++ gives the library author control by having "move" be part 
of the type system that essentially does nothing else than 
applying some constraints. Having "move" as an action is both 
limiting and potentially flawed, since the D compiler does not do 
anything to ensure correctness. If "move" is an action, rather 
than a type system constraint, then it should be backed up with 
semantic analysis IMO.



More information about the Digitalmars-d mailing list