On 2011-06-21 07:34:24 -0400, "Steven Schveighoffer"
<[email protected]> said:
On Mon, 20 Jun 2011 21:59:49 -0400, Michel Fortin
<[email protected]> wrote:
Well, if
a ~= S();
does result in a temporary which get copied and then destroyed, why
have move semantics at all? Move semantics are not just an
optimization, they actually change the semantics. If you have a struct
with a @disabled postblit, should it still be appendable?
Good question. I don't even know how the runtime could avoid calling
postblit, there is no flag saying the postblit is disabled in the
typeinfo (that I know of).
But think about it this way, if you have a function foo:
foo(S)(ref S s, S[] arr)
{
arr[0] = s;
}
Isn't this copy semantics? This is exactly how the D runtime gets the
data. The only difference is, the runtime function is allowed to
accept a temporary as a reference (not possible in a normal function).
... and in the special case where the reference is a rvalue, then it
should have move semantics. See below.
Now, you could force move semantics, if you know the argument is an
rvalue, but I don't know enough about what postblit is used for in
order to say it's fine to use move semantics to move the struct into
the heap.
The reason I say move semantics are an optimization is because:
{
S tmp;
arr ~= tmp;
}
is essentially equivalent to:
arr ~= S();
But the former is copy semantics, the latter can be considered move.
It seems like a smart compiler during optimization could rewrite the
former as the latter, unless the semantics truly are different. Which
is why I'm trying to figure out how postblit can be used ;)
Actually, this should be the equivalent:
import std.algorithm;
S tmp;
arr ~= move(tmp);
While there is no doubt that 'moving' a struct can often be used as an
optimization without changing the semantics, if you want the @disabled
attribute to be useful on the postblit constructor then the language
needs to define when its semantics require 'moving' data and whey then
require 'copying' data, it can't let that only to the choice of the
optimizer.
Things might be clearer if we had a move operator, but instead we have
a 'move' function. There is only one case where I think we can assume
to have move semantics: when a temporary (a rvalue) is assigned to
somewhere. That's also all that's needed for the 'move' function to
work. And that is broken currently when it comes to array appending.
--
Michel Fortin
[email protected]
http://michelf.com/