On Monday, May 2, 2016 at 9:49:24 AM UTC+10, Jim Blandy wrote:
> On Fri, Apr 29, 2016 at 4:43 PM, Gerald Squelart <squel...@gmail.com> wrote:
> 
> > For example, we know how strings behave when moved from* (the original
> > becomes empty), and it'd be nice to be able to use that trick when possible
> > and really needed.
> >
> 
> No, we don't know that. The contract of a move in C++ is simply that the
> source object is safe to destruct, but otherwise in an undefined state. You
> must not make any assumptions about its value.

"contract of a move" -- Where is this written? (Really: If there is an official 
position on this, I'd like to see it!)

The little bit of legalese I could find was about the std:
"""
17.6.5.15 Moved-from state of library types [lib.types.movedfrom]
Objects of types defined in the C++ standard library may be moved from. Move 
operations may be explicitly specified or implicitly generated. Unless 
otherwise specified, such moved-from objects shall be placed in a valid but 
unspecified state.
"""

"Valid but unspecified" is quite different from the loaded word "undefined".
"Valid" to me means that operations should still be possible on the object, but 
the results will just depends on what's left in there after the move.

And one specific example:
"""
30.3.1 Class thread [thread.thread.class]
[...] Objects of class thread can be in a state that does not represent a 
thread of execution. [ Note: A thread object does not represent a thread of 
execution after default construction, after being moved from, or after a 
successful call to detach or join. -- end note ]
"""
This to me implies that a 'thead' object could be moved from, and after that 
its state is valid but does not actually represent a thread of execution.

> It is not always the case that the fastest move implementation leaves the
> source empty. For example, if the string is using inline storage, then a
> move would need to take extra steps to clear the original.

Agreed, sometimes copy is faster, e.g., for PODs, or yes, objects with inline 
storage.

> You write about "us[ing] that trick when possible and really needed", when
> what you're actually saying is "let's depend on undefined behavior." That
> approach is common, and its history is not pretty.

My (more-restricted) point from the following post is that *we* can decide what 
some objects will contain after a move, and we could work with that *defined* 
behavior where possible...

And because it could be misused as you fear, we could introduce annotations to 
ensure that that kind of use is controlled. E.g. Mark reusable-after-move 
objects as such, and use a different word than 'Move' when making these objects 
xvalues. And use type traits so optionally take this optimized path from 
generic functions.


Thinking of it, I suppose lots (all?) of these optimized content-stealing 
actions could be done through differently-named methods (e.g. 'Take()'), so 
they could not possibly be confused with C++ move semantics.
So I could live with a communal decision to forbid any use-after-move ever.
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to