On Saturday, 13 February 2016 at 19:25:37 UTC, Ola Fosheim
Grøstad wrote:
On Saturday, 13 February 2016 at 17:47:54 UTC, Lars T.
Kyllingstad wrote:
[...]
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. [...]
D is all about opinionated solutions. :) In fact, I would go so
far as to say that's what sets D apart from C++, and mostly in a
good way.
[...]
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...
Whose expectations? The formal expectation, as per the C++
standard, is that the moved-from object be left in a "valid but
unspecified state". Basically, as long as it is safe to destroy
or reassign to the moved-from object, you're good.
I hope this is not coming across as me endorsing the practice of
implementing move assignment in terms of swap, because I don't.
But it *is* a rather common practice, enough so that Scott Meyers
felt the need to write an article about it:
http://scottmeyers.blogspot.no/2014/06/the-drawbacks-of-implementing-move.html
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...
A swap is three moves -- actual moves.
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?
What is special is D's requirement that structs be movable by a
raw bit blit, which again enables our particular library
implementation of move().
C++ has no such requirement; for example it is perfectly OK for
an on-stack C++ object to contain a pointer to itself. A D-like
move() on such an object would just produce mayhem.
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.
If you are still talking about this case:
fun(move(someResource));
where fun() throws, like Sönke I don't have a big problem with
the resource being lost there. Given D's semantics, this is what
I would expect. And in D, at least you *know* it is lost, and it
is easy to understand and explain to users. In C++ you have no
idea whether the resource is lost -- it depends on when the
actual move operation happens and when the exception is thrown.
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).
Still not following you. Postblit is not involved in a move at
all -- that's what makes it a move.
If an exception is thrown, the object's destructor is called, and
it would be the destructor's responsibility to break all ties to
other objects.
[...]