[Development] qMoveToConst helper for rvalue references to movable Qt containers?
André Hartmann
andre.hartmann at iseg-hv.de
Mon Oct 29 13:00:07 CET 2018
Hi all,
I fully agree, Olivier.
Looking at https://docs.kdab.com/analysis/qtcreator/clazy.html gives
currently 223 potential detaching containers within range-based for, and
qtbase alone has 46 (https://docs.kdab.com/analysis/qt5/clazy.html).
Even if there may be some false positives, who is going to check and fix
them all? If we don't manage to use the range-based for correctly (for
Qt-containers), why should we force the user to port away from foreach?
Just my two cent.
Best regards,
André
Am 29.10.18 um 12:43 schrieb Olivier Goffart:
> On 10/28/18 8:17 PM, Thiago Macieira wrote:
>> On Sunday, 28 October 2018 11:49:08 PDT Olivier Goffart wrote:
>>> It is a bit ironic that one reason given to deprecate Q_FOREACH is
>>> that it
>>> may copy the container in some cases, while the alternative has the same
>>> problem in much more common cases. (It is my impression that implicitly
>>> shared container such as QList/QVector are by far much more used than
>>> the
>>> one that are not within a typical Qt code base)
>>
>> There are two problems with Q_FOREACH:
>>
>> 1) it will copy containers. For Qt containers, that's rather cheap
>> (two atomic
>> refcount operations), but it's not free. And for Standard Library
>> containers,
>> that is likely very expensive.
>
> But using for(:) with a Qt container will cause a detach in the most
> common case, so I'd say is even worse.
> Which is why i'm saying using this reason is a bit ironic.
>
>>
>> 2) it's implemented by way of a for loop inside a for loop, which is
>> known to
>> throw optimisers out, generating slightly worse code
>
> I would consider that the missed optimization is quite small, if not
> negligible.
> And it can be solved in C++17:
> https://codereview.qt-project.org/243984/
>
>> Our rule already was: Don't use foreach in Qt code. (it was fine in
>> examples)
>>
>> Using iterators and now using the ranged for may need more typing, but
>> produces optimal code.
>>
>>> What could be done is to only deprecate partial specialization of
>>> qMakeForeachContainer for QVarLenghtArray and the standard containers.
>>> Or for containers that do not have a 'detach' function.
>>> That way, users would get a warning for the problematic containers, but
>>> would continue to work just fine with with the containers most Qt
>>> developer
>>> use.
>>
>> I disagree. The optimisation problem is not solved.
>
> I'm ok with discouraging Q_FOREACH, but deprecating such a function need
> more thinking.
> Deprecating means you will force user to port all their codebase away
> from it, which is a huge work. If the rationale is just that they will
> save a couple of atomic operations, i do not think it is worth it.
>
> Deprecating it only for non-shared container seems more logical, since
> we then warn only when there is actually a problem.
>
> And for the Qt shared container case, using foreach is less typing, but
> also less error prone. (do i have to use qAsConst? or make a copy? or
> even return a const object which even lead to more problems)
>
More information about the Development
mailing list