[Development] Move ctors for q_declare_shared types
Thiago Macieira
thiago.macieira at intel.com
Fri Jun 26 22:52:17 CEST 2015
On Friday 26 June 2015 10:45:24 Marc Mutz wrote:
> It introduces a new shared data pointer that's designed to allow users of
> the pointer to have an inline move constructor.
>
> Most of our implicitly shared types already had a move-assignment operator,
> because it's just
>
> QFoo &operator=(QForr &&other) { swap(other); return *this; }
>
> and member-swap was enforced by Q_DECLARE_SHARED since Qt 5.0. I have
> uploaded a series of changes that makes (almost) all Q_DECLARE_SHARED types
> in qtbase nothrow move constructible. That's good. But far from enough.
>
> What is _really_ important to have for _any_ value type is to have nothrow
> move *constructors*, because that's what std::vector uses when reallocating.
[snip]
> Q_DECLARE_SHARED will at some point start to enforce the presence of a
> nothrow move assignment operator, then, later, a nothrow move ctor.
Hi Marc
Thank you for the change, I think this is a good way forward.
As you can see in my comments in the change, I'd just like to explore a way to
make the code less ugly by having fewer macros required in the public headers.
For example: can we make the deallocation function a member of the front-end
class, which is usually exported anyway? This would avoid the ugly need for
two macros in a row like:
Q_GUI_EXPORT Q_SHAREDDATAPOINTER_DECLARE_DTOR(QFontPrivate);
Wouldn't the fact that it's a member function remove the need for the
declaration prior to the class instantiation?
We may need a macro anyway, which I'd advise be called
Q_DECLARE_PUBLIC_SHARED(ClassName)
> Mid-term goal would be to have all implicitly-shared classes use the same
> smart pointer, be nothrow move-assignable, nothrow move-constructible, and
> nothrow *default-constructible* (which requires a trick a la QRegion /
> QString / QVector / QList (QtPrivate::RefCount and a shared null state, or
> else a nullptr d-pointer)), probably by Qt 5.7.
Some of those classes are bigger than one pointer and/or may hold more than
one pointer (for example, QSharedPointer).
I've been playing with null d pointers for the past 3 years and I've never
made it work and I wasn't even trying to keep BC.
> If you don't believe this matters, see comment in qdatetime.h:
>
> // ### Qt6: Using a private here has high impact on runtime
> // on users such as QFileInfo. In Qt 6, the data members
> // should be inlined.
>
> And no, it's not mine. Someone actually measured and found it to be
> unacceptable. Specifically, that the default ctor allocates memory. In fact,
> it's *so* unacceptable that QFileInfo now contains a QVector<QFileInfo>
> instead of a QFileInfo[3], which at face value is ridiculous, but delays
> memory allocations until they are actually needed.
Which is also why I inlined the begin() pointer into
QString/QByteArray/QVector, so it doesn't dereference the d pointer to find out
where it's going to be.
At the same time, I made QUrl not be shared at all. Too much headache.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
More information about the Development
mailing list