Implementing clean and simple move symantics

chris caj@cs.york.ac.uk
Wed Nov 24 17:24:00 GMT 2004


Joe Buck wrote:

>Joe Buck wrote:
>  
>
>>[ memmove better than swap for many types ]
>>    
>>
>
>On Wed, Nov 24, 2004 at 11:01:12AM +0000, Chris Jefferson wrote:
>  
>
>>Hmm.. I'll have to think about this a bit. In actual fact, I think all 
>>of the standard containers look like they can be moved by memmove, and 
>>(quick test program), that is faster even for things like sorting 
>>vectors of vectors and such things. However using memmove involves being 
>>quite careful if its being used for things like sorting, and I suspect 
>>it would be very hard to avoid code duplication (which is what I was 
>>trying to do before). It might simply be unavoidable, in which case 
>>we'll have to live with it :)
>>    
>>
>
>If we specialize for memmove'able types, then clearly we have separate
>code for those types that are not memmove'able.  swap has the advantage
>that it works for everything.  But since swap is 3x worse in many
>situations, I think the price in added complexity is worth paying.
>
>  
>
Sorry, I may have not been clear :)

In my current (hacky) move implementation, I have written a wrapper 
called __move(), which optionally marks a variable as "movable". Then 
a=__move(b) simply performs a=b for non-specialised types and 
(typically) swap(a,b) for specialised types. This means that the 
algorithms themselves only have to be written once.

For memmoving this might be tricker, although actually I think it might 
not be impossible. I would perfer not to have 2 almost identical copies 
of most of the code in libstdc++ depending on if we are memoving or not...

Having said that as I said before, "memmove"ing is better than swap (by 
about a factor of 2) even for those types where swap is efficent, like 
vector and list. However writing algorithms which work with both memmove 
and normal assignment is tricky for a couple of (I think not 
insumantable) reasons, in particular you probably shouldn't memmove to 
and from local variables, so it might be necessary use "containers" 
which can be used like a local variable and allocated on the stack, but 
isn't automatically either created or destroyed, so they can be 
"memmoved" in and out of. (tr1::array does this kind of thing, so it 
shouldn't be hard. I wonder if g++ might lose some optimisation from it tho)

While both the memmove and swap methods of improving things have their 
advantages, I think that memmove is probably better, if slightly tricker 
to program. It's not obvious to me how one system could efficently use 
both methods (because the intrisic difference between them is the 
memmove method is destructive, whereas the swap method leaves both 
variables with valid, if in one case unknown values)

Chris




More information about the Libstdc++ mailing list