[Development] QList

Marc Mutz marc.mutz at kdab.com
Mon Mar 20 09:09:57 CET 2017


On Sunday 19 March 2017 19:48:36 Thiago Macieira wrote:
> On sábado, 18 de março de 2017 15:32:55 PDT Marc Mutz wrote:
> > On Saturday 18 March 2017 19:30:35 Thiago Macieira wrote:
> > > QVector<MyType> someFunction()  // out-of-line
> > > {
> > > 
> > >         QtExclusive::QVector<MyType> vector;
> > >         [ operate and populate vector ]
> > >         return vector;          // automatic move
> > > 
> > > }
> > > 
> > > in user code:
> > >         QtExclusive::QVector<MyType> vector = someFunction();   //
> > > 
> > > automatic move [ mutate some more ]
> > 
> > Breaks (N)RVO.
> 
> How?

Returned Type != (Declared) Return Type != Expected Type (by caller)

For NRVO, all three must be identical, for RVO the last two.

> > And since the code outside has no clue about whether the code inside the
> > function creates a shared or unshared QVector, the compiler will again
> > have to emit the whole QVector copy constructor/detach code (as dead
> > code) at the call site. You promised this would be gone in Qt 6 because
> > of the removal of the unsharable state.
> 
> QtExclusive::QVector's move constructor for QVector always needs to emit
> copying code, since it doesn't know whether the data is shared or not.
> There's no way around that.
>
> QVector's move constructor for QtExclusive::QVector simply adopts the data
> and starts reference-counting.

Sure, I understand that. It's the misuse of QVector when exclusive QVector was 
needed that is the problem:

> You could argue that a function that always returns an unshared vector
> could return QtExclusive::QVector.

Exactly that.

> But we should not allow that in our API
> any more that we allow returning references.

Yes, that was my fear.

The exclusive split sounded like a good idea, like unique_ptr vs. shared_ptr, 
one that could actually win me over to support keeping any form of Qt 
container at all, long-term. Until right now.

If you would propose to make QVector exclusive, maybe with SOO, and provide 
QSharedVector, but to default to QVector in API, you would probably have me on 
board.

It's a fallacy to think that there's a lot of need to return a shared 
collection from APIs. Either you create the collection on request, then an 
exclusive collection would be preferable, as returning it from a function is 
free[1], or you "return" internal state, in which case returning some form of 
view (incl. the case of simply adding begin()/end()) would be the way to go 
(cf. https://codereview.qt-project.org/150658).

Even if your pov is that you should always return an owning collection in 
these cases, and that it therefore has to be a shared one, existing Qt code 
(QObject::children()) shows that even CoW is too slow in these cases 
(children() returns by const-&). If QObject was iterable as a container of 
QObject*, that would both be more convenient as well as faster).

[1] yes, _is_. Ville may correct me if I'm wrong, but afaiu, C++17 makes
 (N)RVO mandatory. Sorry, GCC, you'll have to finally do something about your
 broken NRVO.

> > > Why not std::vector? Because of the ability to put it back into shared
> > > mode,
> > 
> > std::shared_ptr<const std::vector>
> 
> One level of indirection too many. We've been over this.

iow: you'd rather pay some large overhead every time than pay a larger one 
only in cases where it's needed. And this is where we fundamentally disagree.

Even our API guidelines stipulate that you should make common things easy and 
not-so-common things possible. Sharing is _not_ common and it need not be as 
easy as common tasks. Iteration, builing a container from scratch, returning 
by NRVO from a function, these are common things. And CoW pessimises such 
common things - not only performance-wise, but also conceptually: std::vector 
doesn't need qAsConst when used with ranged for loops, std::vector doesn't 
invalidate iterators when copied from...

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, C++ and OpenGL Experts



More information about the Development mailing list