[Development] FileRe: Move ctors for q_declare_shared types

Marc Mutz marc.mutz at kdab.com
Mon Jun 29 17:14:57 CEST 2015


On Monday 29 June 2015 13:44:13 Daniel Teske wrote:
> Instead I will argue that:
> This guarantee is important, valuable and good and Qt not giving this is
> bad.
> 
> So, in this example:
> 
> QSharedPointer<SomeClass> a = [...]
> QSharedPointer<SomeClass> b = [...]
> a  = std::move(b);

I repect Howard a lot, and he's right, to a point, even though I'd argue that 
explicitly clearing a moved-from object that isn't immediately going out of 
scope afterwards should be considered good coding practice, if only to give 
the reader of the code a hint as to what the state of the object is now.

But there are additional constraints here. The std library contains next to no 
out-of-line classes. Destoying the LHS upon move assignment is thus trivial, 
and comes at only minor cost (though the O(N) behaviour _can_ be troublesome 
in practice even so). Consequently, all your examples are of template classes.

But for most Qt types, and indeed the vast majority of those this thread 
is^Wwas originally about, there is an extremly high cost associated with 
destroying the LHS compared to just swapping the state into the RHS: out-of-
line destructor calls. They are not free. They act as compiler-firewalls. The 
compiler loses a lot of the little information about a pimpled object that it 
had, and not only that: it loses information about at the very least all other 
objects of the same type in scope, because it must assume that they are all 
shared. It probably loses *all* information about *all* reference type objects 
in scope, too.

That needs to be seen in connection with the future of the RHS. In the vast 
majority of cases, the RHS just gets its dtor called at the very next 
opportunity. If the LHS was destroyed as part of the move, then the RHS dtor 
will have little to nothing to do. It's an extremely expensive no-op, and 
doubles the number of dtor calls compared to swapping.

So, it doubles the number of dtor calls, and it pessimises all code around it. 
I am not prepared to make that pessimisation for out-of-line types. People who 
use std::move can imo be bothered to clear the moved-from object after the 
move in those miniscule fraction of cases where that actually matters. Forcing 
people to use swap (if, indeed, they can, because swap() doesn't bind to 
rvalues on the rhs) for the common case is bad api design.

For inline types, see https://codereview.qt-project.org/115376

Thanks,
Marc

-- 
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt Experts



More information about the Development mailing list