On 12/07/18 04:17, Jonathan M Davis wrote:> I'm also> not sure if going to copy constructors means that we should do something> different with this. It don't think that it's affected by it, but I could be> missing something.

I actually had that very same concern myself. Andrei does not seem to share it (I talked to him about it during DConf, and he even mentioned it in his talk). He seems to think the two are completely independent.

Like I said, I'm not sure I completely agree. Some of the problems postblit have will also affect us here (specifically, what happens if you want to override a member's behavior, specifically when @disabled.

What tipped the scale for me was this: This DIP is relatively simple. It requires a few changes to all three (compiler, run time and phobos), but small changes to all three. Best of all, this change does not introduce what Andrei called "magic". The changes are easily lowered to existing D code.

Switching to a move-constructor type implementation will make all of those advantages disappear in a puff of bits.


However, I don't agree that opPostMove needs to be nothrow on the basis that
it might be confusing if it's not.

The problem here is that D moves *everywhere*, and it is often quite impossible to make it not move (believe me, I've tried).

With that said, downgrading this to a very hearty recommendation instead of a requirement is fine by me.

Also, as soon as we discuss overriding what happens when an object is moved,
that opens up the question of whether it should be allowed to be @disabled.
What happens when someone does

@disable opPostMove();

What happens today is that if you actually try to move the struct, you will get a compilation error. IMHO, this is the behavior we actually want to keep.

I can actually see some uses for such a step - if you simply cannot have that struct move, a compilation error is preferable to things breaking.

With that said, the moves are so integral to D's code generation that a struct with opPostMove @disabled would not be very useful. I am of the opinion that the programmer can make up their own mind on what to do about it.

However, I would argue that if we're going to take the step of allowing
the programmer to hook into the move process to do custom stuff that we
should also allow it to be outright disabled - the use case that comes to
mind at the moment being stuff like mutexes where the object can't safely be
moved, because it's not only not thread-safe, but it's probably not possible
with the mutex's C API, since you handed a pointer off to it and have no
control over what it does with it.

Like I said above, I completely agree.

Of course, that also opens the question of what should happen with a shared
opPostMove, since presumably a mutex would be in a shared object, and that
would then require that we finish working out shared - though I'd argue that
we would have to disallow moves on a shared object in order to be
thread-safe anyway.

That one is actually handled by the DIP.

opPostMove is called by the compiler when it has just moved the object. This means that, at least as far as the compiler is concerned, the object has no external references to it (or it couldn't move it).

If a struct's pointer is shared, and there are external pointers to update, it is up to the programmer to decide how to handle it (and, yes, @disable might be the only safe option).

By no means do I think that this DIP should be contingent on anything to do
with disallowing moving, but I do think that it if we're going to allow
mucking around with moves like this rather than simply leaving it up to the
compiler that we should seriously consider allowing it to be disabled -

I disagree. I think we should allow it to be disabled whether this DIP goes in or not. On the contrary: this DIP would allow cases to be handled where today they are simply not safe, no matter what you do. In other words, the cases where you'd want to disable move are only reduced by adopting this DIP.

Shachar

Reply via email to