[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