On 2016-04-28 9:09 AM, Gerald Squelart wrote: > On Thursday, April 28, 2016 at 11:00:12 AM UTC+10, Gerald Squelart wrote: >> On Thursday, April 28, 2016 at 10:41:21 AM UTC+10, Ehsan Akhgari wrote: >>> On 2016-04-28 8:00 AM, Gerald Squelart wrote: >>>> On Thursday, April 28, 2016 at 9:35:56 AM UTC+10, Kyle Huey wrote: >>>>> Can we catch this pattern with a compiler somehow? >>>>> >>>>> Foo foo; >>>>> foo.x = thing; >>>>> DoBar(mozilla::Move(foo)); >>>>> if (foo.x) { /* do stuff */ } >>> >>> I think so. We already have an analysis which would detect whether the >>> return value of a function is used somewhere or not. We should be able >>> to reuse that to find the call to DoBar(), and then look for future >>> occurrences of foo used as an rvalue in the rest of the function. Once >>> we detect a use of "foo" as an lvalue, further usages of it as an rvalue >>> in the same function should be OK and not trigger the error. File a bug? >>> >>>> Definitely something that would be nice. >>>> >>>> But if we have/implement such a catcher, I'd like to have an annotation to >>>> say "yep I really want to reuse this moved-from object". >>>> Because sometimes the function will choose not to actually move from an >>>> rvalue-ref, or the object knows to revert to a fully-reusable state, etc. >>> >>> What you're describing sounds like a violation of move semantics, right? >>> The first case should only happen if DoBar doesn't accept an rvalue >>> reference, in which case the code above is definitely doing something >>> that the author did not expect, given that they have used Move(). The >>> latter case sounds completely broken, and if there is an actual good use >>> case for it, the C++ move semantics sound like the wrong tool to achieve >>> that goal to me. >>> >>> If you feel like I'm missing something or you can make a strong argument >>> on why breaking move semantics is OK in some cases, please let me know. :-) >>> >>> Cheers, >>> Ehsan >> >> std::move and mozilla:Move are just casts that make an l-value object *look* >> like an r-value, so that when the compiler considers which 'DoBar' to use, >> one that takes an r-value reference will be picked first. >> >> "Move" is probably not the best name because it gives this impression that >> an actual move happens, but that's what we're stuck with in the standard. >> >> I don't see a "violation of move semantics" in there, could you please >> elaborate on what exact move semantics are violated? >> I'd say it's probably more a "perversion of the move spirit". :-) >> >> In any case, a moved-from object *must* stay valid after that call, because >> at the minimum it will be destroyed at the end of its enclosing scope, by >> invoking its normal destructor, no magic or special path there. >> >> Now what to do with a moved-from object, is I think more a philosophical >> question! Some argue that we should do nothing (except the inevitable >> implied destruction). Others think it should be fine to also allow >> re-assignment (i.e. reuse the variable for something completely different). >> And yet others would allow total reuse. >> >> My position is that 'Move(x)' *usually* means we give the value away and >> don't want to use it again, and therefore a compiler warning/error would >> help catch unexpected reuses; but also that some situations call for reuse >> (e.g. the function doesn't always steal the object's contents, based on >> other factors) and a programmer in the know should be allowed to annotate >> this special case. > > Note that we talked a bit about this situation in: > https://groups.google.com/d/topic/mozilla.dev.platform/VLtl2yL_TlA/discussion > Referring to: > http://mxr.mozilla.org/mozilla-central/source/mfbt/UniquePtr.h#183 > Which talks about conditionally moving from a UniquePtr.
I had missed that thread, but it seems like in that thread you're half agreeing with me, unless I'm missing something? :-) _______________________________________________ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform