|
Boost : |
Subject: Re: [boost] [variant] Please vote for behavior
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2013-02-08 17:20:27
On Fri, Feb 8, 2013 at 12:09 PM, Dave Abrahams <dave_at_[hidden]> wrote:
> on Thu Feb 07 2013, Emil Dotchevski <emildotchevski-AT-gmail.com> wrote:
>> On Thu, Feb 7, 2013 at 6:57 PM, Dave Abrahams <dave_at_[hidden]> wrote:
>>> on Thu Feb 07 2013, Michael Marcin <mike.marcin-AT-gmail.com> wrote:
>>>> Sebastian Redl wrote:
>>>>> On 07.02.2013, at 21:25, Dave Abrahams wrote:
>>>>>> on Thu Feb 07 2013, Sebastian Redl <sebastian.redl-AT-getdesigned.at> wrote:
>>>>>>> On 06.02.2013, at 22:10, Dave Abrahams wrote:
>>>>>>>> on Sat Feb 02 2013, Sebastian Redl <sebastian.redl-AT-getdesigned.at> wrote:
>>>>>>>>> Anything that gives the target object the state the source object had
>>>>>>>>> and is cheaper than a copy is a successful move, really. That is what
>>>>>>>>> a move ultimately is: an optimization of copying.
>>>>>>>>
>>>>>>>> I never liked that characterization. If move were an optimization of
>>>>>>>> copy it would have all the semantics of copy...
>>>>>>>
>>>>>>> I disagree. That would be the case if move were a universally
>>>>>>> applicable optimization, but it isn't. It's a special case
>>>>>>> optimization. In intent, it optimizes copying for the case where the
>>>>>>> resulting state of the source object is irrelevant. In practice, the
>>>>>>> source object must retain some valid state.
>>>>>>>
>>>>>>> This is really similar to how the compiler can only apply some
>>>>>>> optimizations if it can prove certain properties of the code,
>>>>>>> e.g. that two pointers don't alias (various redundant load or store
>>>>>>> eliminations) or that a piece of code is side effect free (loop
>>>>>>> fusion, common subexpression elimination).
>>>>>>
>>>>>> Yes, but those are semantics-preserving transformations. I suppose you
>>>>>> can call move an optimization if you presume the irrelevancy of the
>>>>>> source object has been proven, but usually that proof is part of the
>>>>>> optimization process.
>>>>>
>>>>> That's why move only implicitly kicks in for rvalues and return of
>>>>> local lvalues, where this has indeed been proven. (Sort of. It's
>>>>> actually not true for local lvalues, but then, copy elision can
>>>>> change visible behavior too.)
>>>>> For lvalues, where the compiler can't (or won't) prove it, user
>>>>> intervention is required in the form of std::move. Think of it like
>>>>> of the restrict qualifier for aliasing.
>>>>
>>>> I don't see how move is an optimization of copy since you can move
>>>> noncopyable types.
>>>
>>> Yeah, that's another thing.
>>
>> Is the compiler even allowed to choose between copy and move?
>
> On the basis of whether a move exists, yes. On the basis of whether a
> copy exists, no.
>
>> My understanding is that you can't tell it "this type can't be copied
>> so if I've told you to copy, see if you can move instead".
>
> I think it wouldn't be too hard to code up a copy_else_move(x) function
> along the same lines as std::move(x). You'd probably use some trait to
> detect copiability.
I know you can write code that tells the compiler to move or to copy,
but this doesn't mean that the compiler can move if you told it to
copy. So these operations are independent as far as the language is
concerned, whereas copy constructor elision is allowed entirely at the
discretion of the compiler, because A(A(a)) is the same as A(a).
Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk