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/

Reply via email to