<div dir="ltr"><div dir="ltr"></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 5, 2021 at 10:25 PM Mike Parker via Digitalmars-d <<a href="mailto:digitalmars-d@puremagic.com">digitalmars-d@puremagic.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This is the feedback thread for the first round of Community <br>
Review of DIP 1040, "Copying, Moving, and Forwarding".</blockquote><div><br></div><div>I'm really late to the party here, and there's a lot to catch up, so maybe I'm repeating discussion that already happened... but I think there's a few points that need consideration.<br></div><div><br></div><div>First, I like this DIP, I think this is good for D. That said, I also care deeply about C++ compatibility, and this DIP introduces some serious issues.</div><div><br></div><div>1. This changes the extern(C++) ABI, and it's a major breaking change, yet it's not mentioned in the breaking changes section; every by-val constructor call will have an ABI change, and C++ compatibility will completely explode.</div><div><br></div><div>2. By-val declarations matching f(T&&) is not a great default. It's relatively uncommon in C++ for these arguments to exist unless it makes specific sense, and many cases where it is present C++ uses 'universal references', that infer rval-ness.</div><div><br></div><div>3. ...and even when they do exist, this DIP has different ABI semantics! The C++ `T&&` function still expects the caller to destruct the argument, but in D, the caller will never destruct a moved argument. You talk about this, saying that it's a requirement to pay special attention to the semantic difference, but I don't think that's reasonable. You're going to have endless reports of issues from people that don't read or don't *understand* the difference, and complain their program is crashing.</div><div><br></div><div>4. Is it that C++'s criteria for an EMO matches your definition, or will there emerge cases where a differing EMO assessment will produce a mismatch in calling convention?</div><div><br></div><div>I think there are more problems I can imagine if I dive into the weeds, but at least these need to be addressed in the DIP.</div><div><br></div><div>My off-the-cuff thoughts are:</div><div>1 & 2. Rather than applying EMO semantics to extern(C++) functions by default, and using @value to nominate the default behaviour; since you've accepted an attribute just for C++ disambiguation, why not assume by-val semantics as default, and require an @rval-ref attribute instead to select the C++ move ABI?</div><div>3. Since your EMO semantics don't actually apply to C++, that is, destruction responsibility does NOT carry into the call, I don't think EMO semantics as described actually apply to C++ at all, and shouldn't be attempted. We should use a separate solution for C++ compat (like the attribute I mention above) and EMO semantics have no impact on C++.</div><div><br></div><div>So, in the presence of extern(C++), f(T arg) behaves 'traditionally' (as you describe when applying `@value`), and maybe something like f(T @rvalref arg) introduces the C++ rules (together with some attention to overloading). EMO semantics as described have no applicability to C++.</div><div><br></div><div>Your C++ compatibility section needs a complete do-over as far as I'm concerned. They don't improve the situation for C++ compatibility, they make it worse.</div><div>Perhaps it should be tackled as a separate matter, and in that event, I think the simplest thing to do is to assume f(T) for EMO remains by-val for extern(C++), that is "EMO calling only applies to extern(D) code", and then we make an @rvalref attribute that applies only to extern(C++) for the sake of matching calling convention in a future DIP?</div><div><br></div><div>I might be interested in attempting a DIP that adds an extern(C++)-only rval-ref attribute on top of this DIP; It needs more work. Existing work (for instance, last SAOC) was taken from the perspective that it solves move semantics in D at the same time as interfacing C++. With this DIP addressing elaborate move in D, I think a new approach which ONLY addresses interfacing C++ is an easier sell, and keeps the feature much more isolated.</div><div></div></div></div>